1. 程式人生 > >跨域:跨域及解決方法

跨域:跨域及解決方法

哪些 local cors 請求參數 用戶 ati 行處理 額外 滿足

一、什麽是跨域

廣義的跨域包括:

  1. 資源跳轉:超鏈接<a>跳轉、重定向、表單提交
  2. 資源嵌入:link、ifram、script、img,以及css樣式中的background:url()、@font-face()等外鏈接
  3. 腳本請求:js的ajax請求、js或DOM 中的跨域操作

狹義的跨域:指瀏覽器同源策略限制的請求

註意:並不是所有廣義的跨域操作都不被允許,只有被同源策略限制的跨域操作是不被允許的

二、什麽是瀏覽器同源限制

瀏覽器為了安全考慮不允許訪問不同域下的資源

註意兩點:

  1. 同源限制只是瀏覽器的安全策略,不是http協議的內容
  2. 對於向不同域下發起的請求,瀏覽器會照常發出,服務端處理後也會正常返回結果,但結果會在返回後被瀏覽器攔截

瀏覽器判斷同源的標準:

  1. 請求協議相同
  2. 請求域名相同(包括父子域名都相同,特別註意:域名與對應IP不是同源
  3. 端口號相同

同源限制訪問那些內容:

  1. cookie、LocalStorage、IndexDB等存儲信息無法讀取
  2. DOM對象無法獲取
  3. Ajax請求無法完成

三、處理跨域的方法

1、JSONP

原理:使用<script>可以跨域加載資源。瀏覽器端定義回調方法處理返回數據,跨域請求參數帶回調方法名;服務端需要返回方法名定義的方法,參數為需要的數據,這樣瀏覽器接收後直接以數據為參數調用回調方法

// 瀏覽器端
function fn(data) {
   console.log(
‘在這裏處理返回數據:‘ + data) } <script src="http://a.com/get-date?jsonp=fn"></script> // 服務器端返回數據格式 fn({name: ‘zhangs‘, age: 18})

優點:沒有兼容性問題

缺點:只支持get請求

2、CORS

原理:在高版本的瀏覽器中,發現ajax請求跨域後會在請求頭部添加額外信息添加額外請求(預檢請求option),這樣只要服務端發現跨域請求後在返回頭部通知瀏覽器允許哪些站點跨域請求即可

過程:

  1. CORS在瀏覽器端代碼沒有任何區別,瀏覽器識別到跨域請求後自動對其進行處理,用戶沒有感知。
  2. 服務端處理後,在響應頭部添加Access-Control-Allow-Origin,指定允許請求的源
  3. 瀏覽器收到響應後根據Access-Control-Allow-Origin判斷本站點是否在允許範圍內,允許則接收數據繼續後續操作

確定:兼容性不如jsonp(IE10以上支持)

優點:基本滿足http所有Method類型,也可以指定部分支持Method

3、WebSocket

WebSocket是支持服務端與客戶端雙向通信的應用層(與HTTP同層)協議,基於TCP協議。WebSocket在建立連接時需要借助http,但連接建立後雙方通信過程與http協議無關。

通過WebSocket與跨域服務建立連接,就可以完成跨域請求

優點:協議自定義,減少數據內容

確定:主要用於雙向通信的場景,否則長連接有一定的內存消耗

兼容性IE10以上,不過目前,對於低版本有一定的降級處理途徑,也有Socket.io可以使用

4、postMessage

html5為了解決不同源不能獲取DOM元素的問題,為window對象添加了postMessage方法。

window.postMessage(‘這裏是要發送的信息‘, ‘http://192.168.xxx.xx:3000/‘)

第一個參數:發送的內容

第二個參數:接收消息的源,包括協議類型、域名、端口號

5、nginx跨域處理

第一種:靜態資源添加Access-Control-Allow-Origin配置,原理同CORS(主要針對字體文件跨域請求,css、js等不受同源策略限制)

location / {
  add_header Access-Control-Allow-Origin *;
}

第二種:nginx反向代理解決跨域

實現思路:通過nginx配置一個代理服務器(域名與domain1相同,端口不同)做跳板機,反向代理訪問domain2接口,並且可以順便修改cookie中domain信息,方便當前域cookie寫入,實現跨域登錄

#proxy服務器
server {
    listen       81;
    server_name  www.domain1.com;

    location / {
        proxy_pass   http://www.domain2.com:8080;  #反向代理
        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie裏域名
        index  index.html index.htm;

        # 當用webpack-dev-server等中間件代理接口訪問nignx時,此時無瀏覽器參與,故沒有同源限制,下面的跨域配置可不啟用
        add_header Access-Control-Allow-Origin http://www.domain1.com;  #當前端只跨域不帶cookie時,可為*
        add_header Access-Control-Allow-Credentials true;
    }
}

跨域:跨域及解決方法