前端跨域解決方案

跨域源資源共享

同源:域名、端口、協議均相同
CORS基本思想是使用自定義的HTTP頭部,讓服務器能聲明容許訪問的來源。
使用CORS時,異步請求會被分爲簡單請求(非Preflight)和非簡單請求。javascript

簡單請求

全部的跨域請求(簡單或非簡單)總會包含一個origin的請求頭部,由瀏覽器添加不受用戶控制。值由協議、域名、端口組成,說明請求的來源。下面爲一個Origin頭部示例:java

Origin:http://www.hello.com

服務器接受這個請求,會在響應頭Access-Control-Allow-Origin回發相同的源信息。( * 代表該資源能夠被任意外域訪問)跨域

Access-Control-Allow-Origin:http://www.hello.com

非簡單請求

非簡單CORS請求會在正式請求以前發送一次Preflight請求,獲得確認以後纔會發送真正的XMLHttpRequest請求。瀏覽器自動處理這兩個請求,而且Preflight請求結束後,結果將按照響應中指定的時間緩存起來.因此只是第一次發送這種請求時會多一次HTTP請求.
Preflight請求使用OPTIONS方法,發送下列頭部:瀏覽器

Origin:與簡單請求相同
Access-Control-Request-Method:請求自身使用的方法

如下是一個帶有自定義頭部Custom-Header的使用POST方法發送的請求.緩存

Origin:http://www.hello.com
Access-Control-Request-Method:POST
Access-Control-Request-Headers:Custom-Header
var url = 'http://www.hello.com';
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Custom-Header', 'value');
xhr.send();

服務器經過在響應中發送以下頭部與瀏覽器溝通:bash

Access-Control-Allow-Origin:http://www.hello.com
Access-Control-Allow-Methods:POST,GET
Access-Control-Allow-Headers:Custom-Header
Access-Control-Allow-Max-Age:28000  //表示將Preflight緩存的時長(秒),期間內無需再次發送預請求

另外經過將XMLHttpRequest的withCredentials屬性設置爲true就能夠發送帶憑據(cookie、HTTP認證、客戶端SSL證實等)的跨域請求.服務器

var xhr=new XMLHttpRequest();
xhr.withCredentials=true;

若是服務器接受帶憑據的請求會用下面的HTTP頭部響應:cookie

Access-Control-Allow-Credentials:true

JSONP(JSON with padding)

JSONP由兩部分組成:回調函數+數據,回調函數是當響應到來時應該在頁面中調用的函數,回調函數的名字通常是在請求中指定的.而數據就是傳入回調函數中的JSON數據.JSONP是經過動態<script>元素,爲其src屬性指定一個跨域的URL.異步

function doSomething(response) {
  console.log(response);
}
var script=document.createElement('script');
script.src='http://www.hello.com?callback=doSomething';
document.body.insertBefore(script,document.body.firstChild);

1.定義方法doSomething,而後把doSomething傳給服務器,告知服務器我須要調用doSomething方法.
2.服務端生成JSON.將JSON數據以參數的形式放到doSomething中,這樣就生成了一段js腳本返回給客戶端.
3.客戶端瀏覽器解析script標籤,執行doSomething(JSON)函數

postMessage

otherWindow.postMessage(message, targetOrigin);

otherWindow:指目標窗口,也就是給哪一個window發消息,是window.frames屬性的成員或者由 window.open 方法建立的窗口.
參數說明:message: 是要發送的消息,類型爲 String、Object (IE八、9 不支持);targetOrigin: 是限定消息接收範圍,不限制請使用*

相關文章
相關標籤/搜索