相關文章(zhāng)
欄目分(fēn)類 classification
js跨越自定義header實現跨域訪問
受浏覽器的(de)同源策略限制,JavaSript隻能請求本域内的(de)資源。跨域資源共享(Cross-Origin Resource Sharing, CORS)是爲解決Ajax技術難實現跨域問題而
提出的(de)一個(gè)規範,這(zhè)個(gè)規範試著(zhe)從根本上解決安全的(de)跨域資源共享問題。在此之前,解決此類問題的(de)途徑往往是服務器代理(lǐ)、JSONP等,治标不治本。目
前基本所有浏覽器都已經支持該規範。
一個(gè)域是由schema、host、port三者共同組成,與路徑無關。所謂跨域,是指在http://example-foo.com/域上通(tōng)過XMLHttpRequest對(duì)象調用(yòng)http://example-
bar.com/域上的(de)資源。CORS約定服務器端和(hé)浏覽器在HTTP協議(yì)之上,通(tōng)過一些額外HTTP頭部信息,進行跨域資源共享的(de)協商。服務器端和(hé)浏覽器都必
需遵循規範中的(de)要求。
CORS把HTTP請求分(fēn)成兩類,不同類别按不同的(de)策略進行跨域資源共享協商。
1. 簡單跨域請求。
當HTTP請求出現以下(xià)兩種情況時(shí),浏覽器認爲是簡單跨域請求:
1). 請求方法是GET、HEAD或者POST,并且當請求方法是POST時(shí),Content-Type必須是application/x-www-form-urlencoded, multipart/form-data或著(zhe)tex
t/plain中的(de)一個(gè)值。
2). 請求中沒有自定義HTTP頭部。
對(duì)于簡單跨域請求,浏覽器要做(zuò)的(de)就是在HTTP請求中添加Origin Header,将JavaScript腳本所在域填充進去,向其他(tā)域的(de)服務器請求資源。服務器端收
到一個(gè)簡單跨域請求後,根據資源權限配置,在響應頭中添加Access-Control-Allow-Origin Header。浏覽器收到響應後,查看Access-Control-Allow-Origin
Header,如果當前域已經得(de)到授權,則将結果返回給JavaScript。否則浏覽器忽略此次響應。
2. 帶預檢(Preflighted)的(de)跨域請求。
當HTTP請求出現以下(xià)兩種情況時(shí),浏覽器認爲是帶預檢(Preflighted)的(de)跨域請求:
1). 除GET、HEAD和(hé)POST(only with application/x-www-form-urlencoded, multipart/form-data, text/plain Content-Type)以外的(de)其他(tā)HTTP方法。
2). 請求中出現自定義HTTP頭部。
帶預檢(Preflighted)的(de)跨域請求需要浏覽器在發送真實HTTP請求之前先發送一個(gè)OPTIONS的(de)預檢請求,檢測服務器端是否支持真實請求進行跨域資源訪
問,真實請求的(de)信息在OPTIONS請求中通(tōng)過Access-Control-Request-Method Header和(hé)Access-Control-Request-Headers Header描述,此外與簡單跨域
請求一樣,浏覽器也(yě)會添加Origin Header。服務器端接到預檢請求後,根據資源權限配置,在響應頭中放入Access-Control-Allow-Origin Header、Access-
Control-Allow-Methods和(hé)Access-Control-Allow-Headers Header,分(fēn)别表示允許跨域資源請求的(de)域、請求方法和(hé)請求頭。此外,服務器端還(hái)可(kě)以加入Acce
ss-Control-Max-Age Header,允許浏覽器在指定時(shí)間内,無需再發送預檢請求進行協商,直接用(yòng)本次協商結果即可(kě)。浏覽器根據OPTIONS請求返回的(de)結
果來(lái)決定是否繼續發送真實的(de)請求進行跨域資源訪問。這(zhè)個(gè)過程對(duì)真實請求的(de)調用(yòng)者來(lái)說是透明(míng)的(de)。
XMLHttpRequest支持通(tōng)過withCredentials屬性實現在跨域請求攜帶身份信息(Credential,例如Cookie或者HTTP認證信息)。浏覽器将攜帶Cookie Header
的(de)請求發送到服務器端後,如果服務器沒有響應Access-Control-Allow-Credentials Header,那麽浏覽器會忽略掉這(zhè)次響應。
這(zhè)裏討(tǎo)論的(de)HTTP請求是指由Ajax XMLHttpRequest對(duì)象發起的(de),所有的(de)CORS HTTP請求頭都可(kě)由浏覽器填充,無需在XMLHttpRequest對(duì)象中設置。以下(xià)
是CORS協議(yì)規定的(de)HTTP頭,用(yòng)來(lái)進行浏覽器發起跨域資源請求時(shí)進行協商:
1. Origin。HTTP請求頭,任何涉及CORS的(de)請求都必需攜帶。
2. Access-Control-Request-Method。HTTP請求頭,在帶預檢(Preflighted)的(de)跨域請求中用(yòng)來(lái)表示真實請求的(de)方法。
3. Access-Control-Request-Headers。HTTP請求頭,在帶預檢(Preflighted)的(de)跨域請求中用(yòng)來(lái)表示真實請求的(de)自定義Header列表。
4. Access-Control-Allow-Origin。HTTP響應頭,指定服務器端允許進行跨域資源訪問的(de)來(lái)源域。可(kě)以用(yòng)通(tōng)配符*表示允許任何域的(de)JavaScript訪問資源,但
是在響應一個(gè)攜帶身份信息(Credential)的(de)HTTP請求時(shí),Access-Control-Allow-Origin必需指定具體的(de)域,不能用(yòng)通(tōng)配符。
5. Access-Control-Allow-Methods。HTTP響應頭,指定服務器允許進行跨域資源訪問的(de)請求方法列表,一般用(yòng)在響應預檢請求上。
6. Access-Control-Allow-Headers。HTTP響應頭,指定服務器允許進行跨域資源訪問的(de)請求頭列表,一般用(yòng)在響應預檢請求上。
7. Access-Control-Max-Age。HTTP響應頭,用(yòng)在響應預檢請求上,表示本次預檢響應的(de)有效時(shí)間。在此時(shí)間内,浏覽器都可(kě)以根據此次協商結果決定是否
有必要直接發送真實請求,而無需再次發送預檢請求。
8. Access-Control-Allow-Credentials。HTTP響應頭,凡是浏覽器請求中攜帶了(le)身份信息,而響應頭中沒有返回Access-Control-Allo
w-Credentials: true的(de),浏覽器都會忽略此次響應。
總結:隻要是帶自定義header的(de)跨域請求,在發送真實請求前都會先發送 OPTIONS請求,浏覽器根據OPTIONS請求返回的(de)結果來(lái)決定是否繼
續發送真實的(de)請求進行跨域資源訪問。所以複雜(zá)請求肯定會兩次請求服務端。
js 端的(de)ajax請求:
[javascript]
1. $.ajax({
2. url: "http://test.com",
3. dataType: 'json',
4. type: 'GET',
5. beforeSend: function (xhr) {
6. xhr.setRequestHeader("Test", "testheadervalue");
7. },
服務端的(de)action
8. async: false,
9. cache: false,
10. //contentType: 'application/x-www-form-urlencoded',
11. success: function (sResponse) {
12. }
13. });
[csharp]
1. //允許跨域訪問
2. HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
3. HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT");
4. HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Test");
上一篇:網站建設好應該如何優化(huà)排名和(hé)SEO相關标簽? [返回列表]
下(xià)一篇:網站建設相關技術,網站建設需要注意哪些?
說點什(shén)麽吧
- 全部評論(0)
還(hái)沒有評論,快(kuài)來(lái)搶沙發吧!