注释:http://localhost:8081表示调用方应用服务器(就是在里面发送ajax请求),http://localhost:8080(接口在里面)表示被调用方应用服务器
首先,分析跨域问题产生的原因,三个条件,浏览器限制,请求跨域,请求类型为xmlhttprequest请求,三者缺一个就不会产生跨域问题,我们的解决方案就是破坏这三个条件
解决方案:
1Jsonp解决:jsonp是一个非官方协议是个约定,约定一个参数(下面设这个参数为callback),那么请求的类型就是script类型,返回结果也是一段script代码,代码调用callback传入的function参数就是请求结果,为了有这个约定,服务端是需要改动,添加这个约定的
Jsonp的弊端:1.服务端需要改动2.只能用于get请求,发送其它请求它都会自动转换为get
2原公司解决方法:封装一个接受url的接口保存在.jsp文件中,通过HttpURLConnection在后台发送跨域请求,并解析结果返回回来,我们用的时候就只要去请求这个jsp文件把跨域请求的url传给它由它发送请求,不经过浏览器就不会报跨域问题了
3.一个的javaee模型都是如下图
我们发送跨域请求时是用浏览器(client)发送到被调用方的http服务器(常见的是apache/nginx)然后http服务器判断请求的静态请求(图片,文件等)还是动态请求(后台数据),如果是静态请求就由http服务器直接处理,动态请求就交给应用服务器(tomcat)数据库拿数据,返回给http服务器再返回给浏览器,这就是常见的javaee模型中请求的工作方式
根据这个我们从两方面来解决跨域问题
被调用方解决
浏览器发送请求是先判断他是不是跨域的,是跨域的就会在请求头中加入origind代表调用方的地址
请求返回后浏览器判断响应头中是否有支持跨域的信息,没有就会报跨域错误,所以被调用方请求解决跨域,就是要在响应头中加入支持跨域的信息,有两个地方可以加入,一个是直接在后台接口中加入,另一个就是在http服务器中加入(因为请求会先经过http服务器)
直接加后台加入是通过filter(java中的东西)把信息塞到接口返回的响应头中
http服务器端
slisten和server_name表示http服务器的地址和端口,localtion /中的proxy_pass表示在请求b.com/时是代理到http://localhost:8080/,值得注意的是在发送预检命令时直接返回不经过应用服务器,加快反应速度
对了还有一种直接通过spring的crossOrigin可以实现接口或整个类都允许跨域
调用方解决思路
我们采用的是在调用方的http服务器上加代理,类似这样
我们在a.com请求a/com/ajaxserver它就被代理到http://localhost:8080/test/,浏览器请求的是a.com就没有跨域,当然就不会产生生跨域错误了
参考链接:
慕课网ajax跨域问题解决视频