跨域問題是咱們很是常見的問題,尤爲在跨系統頁面間的調用常常會遇到,解決的方式在網上一搜一大把,這裏整理出我遇到跨域問題解決的方式以及思路,如何安全的解決跨域調用請繼續往下看。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!