成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端跨域及解決方案

wayneli / 1927人閱讀

摘要:但是如果是一級域名相同,二級及以上域名不同的網(wǎng)頁可以通過設(shè)置來共享。設(shè)置有兩種方式前端腳本中設(shè)置服務(wù)器接口設(shè)置時指定所屬的域名為一級域名。服務(wù)器檢查過預檢請求頭之后,確認允許跨域請求,就可以做出回應(yīng)。

一、跨域問題產(chǎn)生的原因

根本原因是由于瀏覽器的“同源政策”。

1.1.同源政策

同源政策由網(wǎng)景公司(Netscape)1995年引入瀏覽器。目前所有瀏覽器都實行這個政策。
所謂同源是指“三個相同”:

協(xié)議相同

域名相同

端口相同

1.2.限制范圍

目前,如果非同源,共有三種行為收到限制。

Cookie、LocalStorage 和 IndexDB 無法讀取。

DOM無法獲取

AJAX請求不能發(fā)送

二、跨域問題處理
2.1 Cookie共享

Cookie是服務(wù)器寫入瀏覽器的信息,只有同源的網(wǎng)頁才能共享。但是如果是一級域名相同,二級(及以上)域名不同的網(wǎng)頁可以通過設(shè)置document.domain來共享cookie。

比如,w1.example.com 和 w2.example.com是不同源的,w1.example.com/index.html (A網(wǎng)頁) 和 w2.example.com/index.html (B網(wǎng)頁)只要設(shè)置相同的document.domain就可以共享Cookie。

設(shè)置domain有兩種方式:1.前端js腳本中設(shè)置 2.服務(wù)器接口設(shè)置cookie時指定Cookie所屬的域名為一級域名。

2.1.1 js設(shè)置domain

在A網(wǎng)頁設(shè)置

document.domain = “example.com”;
document.cookie = “userName = aaa”;

這樣在B網(wǎng)頁就可以讀到這個Cookie

var cookie = document.cookie; // userName = aaa;
2.1.2 服務(wù)器設(shè)置domain
Set-Cookie: userName = aaa ; domain = .example.com ; path = /
2.2 iframe父子窗口共享DOM

如果兩個網(wǎng)頁不同源,就無法拿到對方的DOM。典型例子是iframe和window.open方法打開的窗口,它們與父窗口無法通信。
如果兩個窗口只是二級域名不同,一級域名相同的話,那么設(shè)置document.domain屬性,就可以規(guī)避同源政策。拿到DOM。對于完全不同源的網(wǎng)站,目前有三種方法可以解決跨域窗口通信問題:

片段標識符

window.name

跨文檔通信API

2.2.1 片段標識符

片段標識符指的是URL的#后面的部分,如http://example.com/index.html...。如果只是改變片段標識符部分,頁面不會刷新。
父窗口可以把信息寫入子窗口的片段標識符中,

var src = originURL +  ‘#’ + data;
document.getElementById(‘#iframe’).src = src;

子窗口通過監(jiān)聽hashchange事件得到通知

window.onhashchange = checkMessage;
function checkMessage(){
    var message = window.location.hash;
    //...
}

同樣子窗口也可以修改父窗口的片段標識符。

parent.location.href = target + ‘#" + hash;
2.2.2 window.name

瀏覽器窗口有window.name屬性。這個屬性最大的特點是,無論是否同源,只要在同一個窗口里,前一個網(wǎng)頁設(shè)置了這個屬性,后一個網(wǎng)頁就可以讀取它。

2.2.3 window.postMessage

postMessage是HTML5引入的一個全新的API:跨文檔通信API提供的一個全局方法,允許跨窗口通信,不論是否同源。

父窗口發(fā)送message

var popup = window.open(‘http://aaa.com’,"title");
popup.postMessage(‘Hello World’, ‘http://aaa.com");

子窗口監(jiān)聽message事件

window.addeventlistener(‘message’,function( e ){
    console.log( e.data );
});

message事件的event對象提供三個屬性

event.source 發(fā)送消息的窗口

event.origin 消息發(fā)向的網(wǎng)址

event.data 消息內(nèi)容

2.3 LocalStorage共享

用window.postMessage可解決。

2.4 跨域異步請求(AJAX)

同源政策規(guī)定,AJAX只能發(fā)給同源的網(wǎng)址,否則會報錯。除了用服務(wù)器代理的方法(nginx反向代理等),有以下方法可以解決。

2.4.1 JSONP

原理是利用script標簽的src屬性,接受JSON數(shù)據(jù)。關(guān)鍵在于規(guī)定一個callback方法名,在url中以參數(shù)形式傳給服務(wù)器,由服務(wù)器將數(shù)據(jù)以參數(shù)形式注入callback中,供js腳本使用。
缺點是只能發(fā)送get請求,優(yōu)點是支持老式瀏覽器。

2.4.2 CORS

CORS即跨源資源分享,是W3C標準,是跨源AJAX請求的根本解決方法。相比JSONP,CORS允許任何類型的請求。
目前除了IE之外的所有瀏覽器都支持CORS,IE不能低于IE10版本。
瀏覽器將CORS請求分為兩類,簡單請求和非簡單請求。

2.4.2.1 簡單請求

簡單請求條件:

1. 請求方法 GET、POST、HEAD;
2. http頭信息不超過 Accept 、Accept-Language 、Content-Language、Last-Event-ID;
3. content-type只限于三個值: application/x-www-form-urlencoded、multipart/form-data、text/plain 

對于簡單請求,瀏覽器的處理是直接發(fā)出CORS請求,也就是在頭信息中增加一個字段Origin,該字段說明本次請求是來自哪個源(協(xié)議+域名+端口)。服務(wù)器根據(jù)這個值,判斷是否同意此次請求。

GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

如果Origin指定的域名在許可范圍內(nèi),服務(wù)器返回的相應(yīng),會多幾個頭信息字段。

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

Access-Control-Allow-Origin:該字段必須,它的值要么是請求是Origin的值,要么是一個*,表示接受任意域名的請求。

Access-Control-Allow-Credentials:該字段可選。值是一個布爾值,表示是否允許發(fā)送Cookie,默認為true,表示可以發(fā)送。

Access-Control-Expose-Headers:該字段可選。CORS請求是XHR對象的getResponseHeader( ) 方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expire、Last-Modified、Pragma。如果想要拿到其他字段,就要在Access-Control-Expose-Headers中指定。

注意,如果要將Cookie發(fā)送到服務(wù)器,除了服務(wù)器要設(shè)置Access-Control-Allow-Credentials字段以外,瀏覽器在發(fā)送AJAX請求是也要保證xhr.withCredentials屬性為true,否則瀏覽器既不會向服務(wù)器發(fā)送cookie,服務(wù)器設(shè)置cookie的操作也不會成功。但是默認情況下,該屬性是為true的。
另外需要注意的是,如果要操作Cookie,Access-Control-Allow-Origin就不能設(shè)置為*,必須明確是哪個網(wǎng)址過來的請求。

對于非簡單請求:
非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP請求,成為“預檢”請求。
瀏覽器先詢問服務(wù)器,當前網(wǎng)頁所在域名是否在服務(wù)器的許可名單中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答復,瀏覽器才會發(fā)出正式的XMLHttpRequest請求,否則報錯。
預檢請求的方法是OPTIONS,頭信息中的關(guān)鍵字是Origin,標識請求來自哪個源。另外還包含兩個特殊字段:

Access-Control-Request-Method:該字段是必須的,用于流出瀏覽器的CORS請求會用到那些HTTP方法。

Access-Control-Request-Headers:該字段用來指定CORS會額外發(fā)出的頭信息字段。

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

服務(wù)器檢查過預檢請求頭之后,確認允許跨域請求,就可以做出回應(yīng)。
響應(yīng)頭部信息的關(guān)鍵字段是Access-Control-Allow-Origin,為*或者一個完整域名,表示允許的請求來源。
如果服務(wù)器否定了“預檢”請求,會返回一個正常的HTTP回應(yīng),不包含任何CORS相關(guān)的字段。這是瀏覽器會認定,服務(wù)器不同意預檢請求,因此會觸發(fā)一個錯誤,唄XHR對象的onerror函數(shù)捕獲。并在控制臺打印。
成功的話還有幾個與CORS相關(guān)的響應(yīng)頭字段:

Access-Control-Allow-Methods:必須。表示服務(wù)器支持的跨域請求方法。注意會返回所有支持的方法,以此避免多次預檢請求。

Access-Control-Allow-Headers:如果請求頭包含該字段,則服務(wù)器響應(yīng)也是必須的。

Access-Control-Allow-Credentials:是否支持cookie傳輸

Access-Control-Max-Age:可選。用來指定本次預檢請求的有效期,單位為秒。在此期間不用發(fā)出另一條預檢請求。

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

一旦服務(wù)器通過了預檢請求,以后每次瀏覽器正常的CORS請求,就和簡單請求一樣,會有一個Origin字段,服務(wù)器回應(yīng)也會有一個Access-Control-Allow-origin頭信息字段。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90154.html

相關(guān)文章

  • 理解域及常用解決方案

    摘要:跨域的產(chǎn)生不用多講,作為一名前端開發(fā)人員,相信大家都知道跨域是因為瀏覽器的同源策略所導致的。瀏覽器引入同源策略主要是為了防止,攻擊。其指明了實際請求所允許使用的方法。 跨域,相信大家無論是在工作中還是在面試中經(jīng)常遇到這個問題,常常在網(wǎng)上看到別人所整理的一些方法,看似知道是怎么回事,但如果沒有動手實踐過,總覺得自己沒有真正的掌握,在這里,通過自己認真思考整理一些常用的方法。 跨域的產(chǎn)生 ...

    paney129 評論0 收藏0
  • 理解域及常用解決方案

    摘要:跨域的產(chǎn)生不用多講,作為一名前端開發(fā)人員,相信大家都知道跨域是因為瀏覽器的同源策略所導致的。瀏覽器引入同源策略主要是為了防止,攻擊。其指明了實際請求所允許使用的方法。 跨域,相信大家無論是在工作中還是在面試中經(jīng)常遇到這個問題,常常在網(wǎng)上看到別人所整理的一些方法,看似知道是怎么回事,但如果沒有動手實踐過,總覺得自己沒有真正的掌握,在這里,通過自己認真思考整理一些常用的方法。 跨域的產(chǎn)生 ...

    only_do 評論0 收藏0
  • 理解域及常用解決方案

    摘要:跨域的產(chǎn)生不用多講,作為一名前端開發(fā)人員,相信大家都知道跨域是因為瀏覽器的同源策略所導致的。瀏覽器引入同源策略主要是為了防止,攻擊。其指明了實際請求所允許使用的方法。 跨域,相信大家無論是在工作中還是在面試中經(jīng)常遇到這個問題,常常在網(wǎng)上看到別人所整理的一些方法,看似知道是怎么回事,但如果沒有動手實踐過,總覺得自己沒有真正的掌握,在這里,通過自己認真思考整理一些常用的方法。 跨域的產(chǎn)生 ...

    wemallshop 評論0 收藏0
  • 關(guān)于javascript域及JSONP的原理與應(yīng)用

    摘要:因為同源策略的限制,我們不能在與外部服務(wù)器進行通信的時候使用。這個是跨域服務(wù)器取數(shù)據(jù)的接口,參數(shù)為回調(diào)函數(shù)的名字,返回的格式為原理首先在客戶端注冊一個然后把的名字傳給服務(wù)器。 一、同源策略 同源策略,它是由Netscape提出的一個著名的安全策略,現(xiàn)在所有的可支持javascript的瀏覽器都會使用這個策略。 為什么需要同源策略,這里舉個例子: 假設(shè)現(xiàn)在沒有同源策略,會發(fā)生什么事...

    CoderBear 評論0 收藏0
  • jsonp跨域獲取數(shù)據(jù)實現(xiàn)百度搜索

    摘要:同源策略做了很嚴格的限制,但是在實際的場景中,又確實有很多地方需要突破同源策略的限制,也就是我們常說的跨域。使用跨域由于同源策略,一般來說位于的網(wǎng)頁無法與不是的服務(wù)器溝通,而的元素是一個例外。 本菜雞最近在寫某個頁面請求數(shù)據(jù)時,報了如下的錯誤。 Failed to load https://...:No Access-Control-Allow-Origin header is pre...

    Tikitoo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<