摘要:在接觸前端開發(fā)起,跨域這個詞就一直以很高的頻率在我們學(xué)習(xí)工作中重復(fù)出現(xiàn),最近在工作中遇到了跨域的相關(guān)問題,這里我把它總結(jié)記錄一下。
在接觸前端開發(fā)起,跨域這個詞就一直以很高的頻率在我們學(xué)習(xí)工作中重復(fù)出現(xiàn),最近在工作中遇到了跨域的相關(guān)問題,這里我把它總結(jié)記錄一下。
關(guān)于跨域,有N種類型,現(xiàn)在我只專注于ajax請求跨域(ajax跨域只是屬于瀏覽器”同源策略”中的一部分,其它的這里不做介紹),內(nèi)容大概如下:
什么是ajax跨域?如何解決ajax跨域?如何分析ajax跨域?
一、什么是Ajax跨域
Ajax跨域的原理
ajax出現(xiàn)請求跨域錯誤問題,主要原因就是因為瀏覽器的“同源策略”。
CORS請求原理
CORS是一個W3C標(biāo)準(zhǔn),全稱是”跨域資源共享”(Cross-origin resource sharing)。它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
基本上目前所有的瀏覽器都實現(xiàn)了CORS標(biāo)準(zhǔn),其實目前幾乎所有的瀏覽器ajax請求都是基于CORS機(jī)制的,只不過可能平時前端開發(fā)人員并不關(guān)心而已(所以說其實現(xiàn)在CORS解決方案主要是考慮后臺該如何實現(xiàn)的問題)。
下面是一個簡化版的實現(xiàn)原理圖:
??
如何判斷是否是簡單請求?
瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。只要同時滿足以下兩大條件,就屬于簡單請求。
l 請求方法是以下三種方法之一:HEAD,GET,POST
l HTTP的頭信息不超出以下幾種字段:
Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(只限于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain)
凡是不同時滿足上面兩個條件,就屬于非簡單請求。
ajax跨域的表現(xiàn)
現(xiàn)象一: No "Access-Control-Allow-Origin" header is present on the requested resource,并且The response had HTTP status code 404
??
出現(xiàn)這種情況的原因如下:
l 本次ajax請求是“非簡單請求”,所以請求前會發(fā)送一次預(yù)檢請求(OPTIONS)
l 服務(wù)器端后臺接口沒有允許OPTIONS請求,導(dǎo)致無法找到對應(yīng)接口地址
解決方案: 后端允許options請求。
現(xiàn)象二: No "Access-Control-Allow-Origin" header is present on the requested resource,并且The response had HTTP status code 405
??
這種情況下:
l 后臺方法允許OPTIONS請求,但是一些配置文件中(如安全配置),阻止了OPTIONS請求,才會導(dǎo)致這個現(xiàn)象
解決方案: 后端關(guān)閉對應(yīng)的安全配置。
現(xiàn)象三: No "Access-Control-Allow-Origin" header is present on the requested resource,并且status 200
??
這種情況下:
l 服務(wù)器端后臺允許OPTIONS請求,并且接口也允許OPTIONS請求,但是頭部匹配時出現(xiàn)不匹配現(xiàn)象,比如origin頭部檢查不匹配,比如少了一些頭部的支持(如常見的X-Requested-With頭部),然后服務(wù)端就會將response返回給前端,前端檢測到這個后就觸發(fā)XHR.onerror,導(dǎo)致前端控制臺報錯
解決方案: 后端增加對應(yīng)的頭部支持。
現(xiàn)象四: heade contains multiple values ","
??
這種問題出現(xiàn)的主要原因就是進(jìn)行跨域配置的人不了解原理,導(dǎo)致了重復(fù)配置,如:
l 常見于.net后臺(一般在web.config中配置了一次origin,然后代碼中又手動添加了一次origin(比如代碼手動設(shè)置了返回*))
l 常見于.net后臺(在IIS和項目的webconfig中同時設(shè)置Origin:*)
解決方案(一一對應(yīng)):
建議刪除代碼中手動添加的*,只用項目配置中的即可;
建議刪除IIS下的配置*,只用項目配置中的即可。
二、如何解決ajax跨域
一般ajax跨域解決就是通過JSONP解決或者CORS解決,如以下:(注意,現(xiàn)在已經(jīng)幾乎不會再使用JSONP了,所以這里重點介紹CORS)
CORS解決跨域問題
CORS的原理上文中已經(jīng)介紹了,這里主要介紹的是,實際項目中,后端應(yīng)該如何配置以解決問題,這里是一些常見的后端解決方案:
PHP后臺配置:
PHP后臺得配置幾乎是所有后臺中最為簡單的,遵循如下步驟即可:
l 第一步:配置Php 后臺允許跨域
??
l 第二步:配置Apache web服務(wù)器跨域(httpd.conf中)
原始代碼:
??
改為以下代碼:
??
Node.js后臺配置(express框架):
Node.js的后臺也相對來說比較簡單就可以進(jìn)行配置。只需用express如下配置:
??
JAVA后臺配置:
JAVA后臺配置只需要遵循如下步驟即可:
l 第一步:獲取依賴jar包下載 cors-filter-1.7.jar, java-property-utils-1.9.jar 這兩個庫文件放到lib目錄下。(放到對應(yīng)項目的webcontent/WEB-INF/lib/下)
l 第二步:如果項目用了Maven構(gòu)建的,請?zhí)砑尤缦乱蕾嚨絧om.xml中:(非maven請忽視)
??
其中版本應(yīng)該是最新的穩(wěn)定版本,CORS過濾器
l 第三步:添加CORS配置到項目的Web.xml中( App/WEB-INF/web.xml)
??
注意:以上配置文件請放到web.xml的前面,作為第一個filter存在(可以有多個filter的)
l 第四步:可能的安全模塊配置錯誤(注意,某些框架中-譬如公司私人框架,有安全模塊的,有時候這些安全模塊配置會影響跨域配置,這時候可以先嘗試關(guān)閉它們)
NET后臺配置:
.NET后臺配置可以參考如下步驟:
l 第一步:網(wǎng)站配置:
打開控制面板,選擇管理工具,選擇iis;右鍵單擊自己的網(wǎng)站,選擇瀏覽;打開網(wǎng)站所在目錄,用記事本打開web.config文件添加下述配置信息,重啟網(wǎng)站
??
如果配置仍然出問題,可以考慮增加更多的headers允許,比如:
??
l 第二步:其它更多配置,如果第一步進(jìn)行了后,仍然有跨域問題,可能是:
l 接口中有限制死一些請求類型(比如寫死了POST等),這時候請去除限 制
l 接口中,重復(fù)配置了Origin:*,請去除即可
l IIS服務(wù)器中,重復(fù)配置了Origin:*,請去除即可
代理請求方式解決接口跨域問題
注意,由于接口代理是有代價的,所以這個僅是開發(fā)過程中進(jìn)行的。
與前面的方法不同,前面CORS是后端解決,而這個主要是前端對接口進(jìn)行代理,也就是:
l 前端ajax請求的是本地接口
l 本地接口接收到請求后向?qū)嶋H的接口請求數(shù)據(jù),然后再將信息返回給前端
l 一般用node.js即可代理
關(guān)于如何實現(xiàn)代理,這里就不重點描述了,方法和多,也不難,基本都是基于node.js的。搜索關(guān)鍵字node.js,代理請求即可找到一大堆的方案。
三、如何分析ajax跨域
抓包請求數(shù)據(jù)
第一步當(dāng)然是得知道我們的ajax請求發(fā)送了什么數(shù)據(jù),接收了什么,做到這一步并不難,也不需要fiddler等工具,僅基于Chrome即可
l Chrome瀏覽器打開對應(yīng)發(fā)生ajax的頁面,F(xiàn)12打開Dev Tools
l 發(fā)送ajax請求
l 右側(cè)面板->NetWork->XHR,然后找到剛才的ajax請求,點進(jìn)去
示例一(正常的ajax請求)
??
上述請求是一個正確的請求,為了方便,我把每一個頭域的意思都表明了,我們可以清晰的看到,接口返回的響應(yīng)頭域中,包括了:
??
所以瀏覽器接收到響應(yīng)時,判斷的是正確的請求,自然不會報錯,成功的拿到了響應(yīng)數(shù)據(jù)。
示例二(跨域錯誤的ajax請求)
??
這個請求中,接口Allow里面沒有包括OPTIONS,所以請求出現(xiàn)了跨域
??
這個請求中,Access-Control-Allow-Origin: *出現(xiàn)了兩次,導(dǎo)致了跨域配置沒有正確配置,出現(xiàn)了錯誤。更多跨域錯誤基本都是類似的,就是以上三樣沒有滿足(Headers,Allow,Origin),這里不再一一贅述。
示例三(與跨域無關(guān)的ajax請求)
并不是所有的ajax請求錯誤都與跨域有關(guān),所以請不要混淆,比如以下:
??
??
比如這個請求,它的跨域配置沒有一點問題,它出錯僅僅是因為request的Accept和response的Content-Type不匹配而已。
基本上都是這樣去分析一個ajax請求,通過Chrome就可以知道了發(fā)送了什么數(shù)據(jù),收到了什么數(shù)據(jù),然后再一一比對就知道問題何在了。
最后,跨域是一個老生常談的話題,網(wǎng)上也有大量跨域的資料,并且有不少精品。
喜歡文章的可以加微信~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/54774.html
摘要:先說下我面試情況,我一共面試了家公司。篇在我面試的眾多公司里,只有同城的面問到相關(guān)問題,其他公司壓根沒問。我自己回答的是自己開發(fā)組件面臨的問題。完全不用擔(dān)心對方到時候打電話核對的問題。 2019的5月9號,離發(fā)工資還有1天的時候,我的領(lǐng)導(dǎo)親切把我叫到辦公室跟我說:阿郭,我們公司要倒閉了,錢是沒有的啦,為了不耽誤你,你趕緊出去找工作吧。聽到這話,我虎軀一震,這已經(jīng)是第2個月沒工資了。 公...
摘要:拿到秋招的同學(xué),如確定入職需與用人單位簽署三方協(xié)議,以保證雙方的利益不受損失。當(dāng)然每個崗位所要求的側(cè)重點不同,但卻百變不離其宗。方法論要想達(dá)成某個目標(biāo)都有其特定的方法論,學(xué)習(xí)技術(shù)也不例外,掌握適當(dāng)?shù)膶W(xué)習(xí)方法才能事半功倍。 寫在前面的話 筆者從17年的2月份開始準(zhǔn)備春招,其中遇到不少坑,也意識到自己走過的彎路。故寫了這篇文章總結(jié)一番,本文適合主動學(xué)習(xí)的,對自己要學(xué)的課程不明確的,對面試有...
摘要:拿到秋招的同學(xué),如確定入職需與用人單位簽署三方協(xié)議,以保證雙方的利益不受損失。當(dāng)然每個崗位所要求的側(cè)重點不同,但卻百變不離其宗。方法論要想達(dá)成某個目標(biāo)都有其特定的方法論,學(xué)習(xí)技術(shù)也不例外,掌握適當(dāng)?shù)膶W(xué)習(xí)方法才能事半功倍。 寫在前面的話 筆者從17年的2月份開始準(zhǔn)備春招,其中遇到不少坑,也意識到自己走過的彎路。故寫了這篇文章總結(jié)一番,本文適合主動學(xué)習(xí)的,對自己要學(xué)的課程不明確的,對面試有...
閱讀 1771·2021-11-25 09:43
閱讀 15322·2021-09-22 15:11
閱讀 2623·2019-08-30 13:19
閱讀 2009·2019-08-30 12:54
閱讀 1815·2019-08-29 13:06
閱讀 923·2019-08-26 14:07
閱讀 1612·2019-08-26 10:47
閱讀 3027·2019-08-26 10:41