跨域踩坑經驗總結(內涵:跨域知識科普)

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

什麼是跨域?

什麼是Cross-origin_resource_sharing? 跨域請求存在的緣由:因爲瀏覽器的同源策略,即屬於不一樣域的頁面之間不能相互訪問各自的頁面內容。css

跨域使用的場景?

  1. 域名不一樣
    • www.jiuyescm.comwww.jiuye.com即爲不一樣的域名
  2. 二級域名相同,子域名不一樣
    • a.jiuyescm.comb.jiuyescm.com爲子域不一樣
  3. 端口不一樣,協議不一樣
    • http://www.jiuyescm.comhttps://www.jiuyescm.com
    • www.jiuyescm.com:8888www.jiuyescm.com:8080

解決跨域的方式?

  1. jsonp
    • 安全性差,已經不推薦
  2. CORS(W3C標準,跨域資源共享 - Cross-origin resource sharing)
    • 服務端設置,安全性高,推薦使用
  3. websocke
    • 特殊場景時使用,不屬於常規跨域操做
  4. 代理服務(nginx)
    • 可做爲服務端cors配置的一種方式,推薦使用

前端、後端如何配合處理跨域?

ps. 咱們這裏只介紹:CORS處理方式。前端

跨域常見錯誤

首先讓咱們看一下前端報出的跨域錯誤信息java

第一種:No 'Access-Control-Allow-Origin' header is present on the requested resource,而且The response had HTTP status code 404jquery

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 405github

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實現原理和機制不瞭解致使。

突如其來的OPTIONS請求?

有時你會發現明明請求的是POST、GET、PUT、DELETE,可是瀏覽器中看到的確實OPTION,,爲何會變成OPTION?

緣由:由於本次Ajax請求是「非簡單請求」,因此請求前會發送一次預檢請求(OPTIONS),這個操做由瀏覽器本身進行。若是服務器端後臺接口沒有容許OPTIONS請求,將會致使沒法找到對應接口地址,所以須要服務端提供相應的信息到response header中,繼續往下看。

後端須要返回的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下沒法正常工做而且還報錯,額。。。。。

Ajax跨域請求跨平臺兼容性問題

問題緣由:由於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!

轉自:https://ningyu1.github.io/site/post/92-cors-ajax/

相關文章
相關標籤/搜索