欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

AJAX跨域问题解决方法(3)——被调用方解决跨域

程序员文章站 2022-04-16 08:28:03
被调用方解决跨域是指在HTTP响应头中增加指定的字段,允许调用方调用 可以在两种地方增加1.apache/nginx(HTTP服务器)2.tomcat(应用服务器) 浏览器如何判断跨域?仔细观察可以发现,跨域请求的请求头中多了一个Origin字段,这个字段的值是当前域的信息。浏览器发现请求是跨域的时 ......

被调用方解决跨域是指在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既可以加在类中,也可以加在具体的方法中,加在类中代表着这个类所有的方法支持跨域,加在方法中代表着这个方法支持跨域。