zoukankan      html  css  js  c++  java
  • AJAX跨域问题解决方法(3)——被调用方解决跨域

    被调用方解决跨域是指在HTTP响应头中增加指定的字段,允许调用方调用

    可以在两种地方增加
    1.apache/nginx(HTTP服务器)
    2.tomcat(应用服务器)

    浏览器如何判断跨域?
    仔细观察可以发现,跨域请求的请求头中多了一个Origin字段,这个字段的值是当前域的信息。
    浏览器发现请求是跨域的时候,会在当前请求的请求头中添加一个当前域的信息的字段,等返回后检查响应头中有没有相应的信息。
    如果没有,则报错。

    浏览器先执行还是先判断?
    简单请求先执行后判断,非简单请求先判断后执行。

    何为简单请求?
    简单请求就是请求header里:
    1.无自定义请求头
    2.Content-Type为以下几种:
    text/plain
    multipart/form-data
    application/x-www-form-urlencoded
    常见方法为:GET、HEAD、POST

    非简单请求:
    1.put,delete方法的aja请求
    2.发送json格式的ajax请求
    3.带自定义头的ajax请求
    对于非简单请求,浏览器会在htpp的请求头中添加一条字段:
    Access-Control-Request-Headers: Content-Type
    即:询问服务器是否允许这个Content-Type这个请求头
    此时,为了使得非简单请求通过预检,则需要在响应头中添加以下字段:
    Access-Control-Allow-Headers: Content-Type
    即支持Content-Type

    执行简单请求的跨域代码,发现后台服务器正常返回数据,在chrome的network中也可以找到返回的数据。
    所以,简单请求浏览器先执行然后判断。
    当非简单请求发生跨域时,浏览器检测到非简单的跨域请求,会自动发出一个OPTION请求,就是所谓的预检命令,当预检通过的时候,才会把真正的请求发出去。
    即非简单请求在network中可以看到两次请求,一次OPTION请求,一次真正的请求。
    由于非简单命令太过耗费时间(请求两次),所以可以在响应请求头中添加一个字段:
    Access-Control-Max-Age: 3600 (单位为秒)
    即在一个小时内,该请求可以缓存。
    此时,在第一次访问这个方法需要请求两次,而第二次则只需要请求一次,去除了预检命令。
    但是,此时去除Access-Control-Max-Age与Access-Control-Allow-Headers,则请求依然会成功,因为该请求已经被缓存。

    一:被调用方 - Filter解决方案

    Filter解决方案主要是在http响应头上添加如下信息:
    Access-Control-Allow-Origin: 域名
    只要域名包含请求头中Origin字段的值,则支持当前跨域
    如果 Access-Control-Allow-Origin: * ,则支持所有域名访问
    该字段必填

    如果加上 Access-Control-Allow-Methods: 请求方法,则表示只支持特定的请求方法进行跨域。
    如Access-Control-Allow-Methods: GET则表示只支持GET方法进行跨域。
    如果Access-Control-Allow-Methods: * 则表示支持所有方法进行跨域,此时,写了和没写一样。
    此字段可选,非必填。

    二:被调用方 - Nginx解决方案

    使用Nginx配置代理服务器,前端请求地址改为Nginx配置代理服务器。
    在Nginx中配置Filter解决方案中类似的响应头可以实现。

    三:被调用方 - Apache解决方案

    类似于Nginx解决方案,只不过使用Apache代替Nginx。

    四:被调用方 - Spring框架解决方案

    Spring框架中有个名为@CrossOrigin的注解,该注解被用来处理跨域请求。
    在使用Spring框架的基础上,在代码中使用@CrossOrigin注解,可以解决跨域问题。
    @CrossOrigin既可以加在类中,也可以加在具体的方法中,加在类中代表着这个类所有的方法支持跨域,加在方法中代表着这个方法支持跨域。

  • 相关阅读:
    git使用小结
    关于vtordisp知多少?
    虚函数与虚继承寻踪
    最简git Server配置
    StarUML序
    CacheHelper对缓存的控制
    Web Service的一些经验和技巧总结
    月份信息二维坐标图绘制(绘制箭头算法)续
    dynamic与xml的相互转换
    如何将XML与OBJECT进行相互转换(泛型以及通用方法)
  • 原文地址:https://www.cnblogs.com/karthuslorin/p/8531598.html
Copyright © 2011-2022 走看看