跨域问题是咱们很是常见的问题,尤为在跨系统页面间的调用常常会遇到,解决的方式在网上一搜一大把,这里整理出我遇到跨域问题解决的方式以及思路,如何安全的解决跨域调用请继续往下看。javascript
什么是Cross-origin_resource_sharing? 跨域请求存在的缘由:因为浏览器的同源策略,即属于不一样域的页面之间不能相互访问各自的页面内容。css
www.jiuyescm.com
和www.jiuye.com
即为不一样的域名a.jiuyescm.com
和b.jiuyescm.com
为子域不一样http://www.jiuyescm.com
和https://www.jiuyescm.com
www.jiuyescm.com:8888
和www.jiuyescm.com:8080
ps. 咱们这里只介绍:CORS处理方式。前端
首先让咱们看一下前端报出的跨域错误信息java
第一种:No 'Access-Control-Allow-Origin' header is present on the requested resource
,而且The response had HTTP status code 404
jquery
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 404.
ps.而且The response had HTTP status code 404nginx
问题缘由:服务器端后台没有容许OPTIONS请求git
第二种:No 'Access-Control-Allow-Origin' header is present on the requested resource
,而且The response had HTTP status code 405
github
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 405.
ps.而且The response had HTTP status code 405web
问题缘由:服务器端后台容许了OPTIONS请求,可是某些安全配置阻止了OPTIONS请求ajax
第三种:No 'Access-Control-Allow-Origin' header is present on the requested resource
,而且The response had HTTP status code 200
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access.
ps.而且The response had HTTP status code 200
问题缘由:服务器端后台容许了OPTIONS请求,而且OPTIONS请求没有被阻止,可是头部不匹配。
第四种:heade contains multiple values '*,*'
,而且The response had HTTP status code 200
XMLHttpRequestcannot load http://b.domain.com. The 'Access-Control-Allow-Origin' header contains multiple values'*, *', but only one is allowed. Origin 'http://a.domain.com' is therefore notallowed access.
ps.而且The response had HTTP status code 200
问题缘由:设置屡次Access-Control-Allow-Origin=*,多是配置的人对CORS实现原理和机制不了解致使。
有时你会发现明明请求的是POST、GET、PUT、DELETE,可是浏览器中看到的确实OPTION,,为何会变成OPTION?
缘由:由于本次Ajax请求是“非简单请求”,因此请求前会发送一次预检请求(OPTIONS),这个操做由浏览器本身进行。若是服务器端后台接口没有容许OPTIONS请求,将会致使没法找到对应接口地址,所以须要服务端提供相应的信息到response header中,继续往下看。
# 服务端容许访问的域名 Access-Control-Allow-Origin=https://idss-uat.jiuyescm.com # 服务端容许访问Http Method Access-Control-Allow-Methods=GET, POST, PUT, DELETE, PATCH, OPTIONS # 服务端接受跨域带过来的Cookie,当为true时,origin必须是明确的域名不能使用* Access-Control-Allow-Credentials=true # Access-Control-Allow-Headers 代表它容许跨域请求包含content-type头,咱们这里不设置,有须要的能够设置 #Access-Control-Allow-Headers=Content-Type,Accept # 跨域请求中预检请求(Http Method为Option)的有效期,20天,单位秒 Access-Control-Max-Age=1728000
ps. 若是跨域须要携带cookie去请求,Access-Control-Allow-Credentials
必须为true,可是须要注意当Access-Control-Allow-Credentials=true
时,Access-Control-Allow-Origin
就不能为” * “ ,必须是明确的域名,固然能够多个域名使用 “,” 分割
若是是浏览器直接访问跨域请求url,只要服务端返回 “Access-Control-Allow-X” 系列header在response中便可成功访问。
若是是ajax发起的请求该如何处理?
第一种:请求不须要携带cookie
$.ajax({
url : 'url', data : data, dataType: 'json', type : 'POST', crossDomain: true, contentType: "application/json", success: function (data) { var a=JSON.stringify(data); if(data.result==true){ ........... }else{ ........... } }, error:function (data) { var a=JSON.stringify(data); alert(a); } });
ps. 增长crossDomain=true
第二种:请求须要携带cookie
$.ajax({
url : 'url', data : data, dataType: 'json', type : 'POST', xhrFields: { withCredentials: true }, crossDomain: true, contentType: "application/json", success: function (data) { var a=JSON.stringify(data); if(data.result==true){ ........... }else{ ........... } }, error:function (data) { var a=JSON.stringify(data); alert(a); } });
ps. 增长crossDomain与xhr.withCredentials,发送Ajax时,Request header中便会带上 Cookie 信息。
到这里你觉得跨域的相关都介绍完毕了?太天真
最后还有一个终极boss问题,是什么问题呢?
上面的第二种携带cookie的跨域请求调用方式在IOS下能够正常工做,可是在Android下没法正常工做而且还报错,额。。。。。
问题缘由:由于Android下的webview不兼容这个写法,使用标准的 beforeSend(XHR) 替换
xhrFields: { withCredentials: true }
ps. webview不兼容的写法,firefox下也不兼容
标准的写法:
$.ajax({
type: "POST", url: "url", data:datatosend, dataType:"json", beforeSend: function(xhr) { xhr.withCredentials = true; } crossDomain:true, success: function (data) { var a=JSON.stringify(data); if(data.result==true){ ........... }else{ ........... } }, error:function (data) { var a=JSON.stringify(data); alert(a); } });
到这跨域的相关使用就介绍完毕,此次是真的结束了。Keep Real!