有關同源戰略細緻引見,請看
這裏
JSONP
JSONP是服務器與客戶端跨源通訊的經常運用要領。最大特性就是簡樸實用,老式瀏覽器悉數支撐,服務器革新異常小。
它的基本思想是,網頁經由過程增加一個<script>
元素,向服務器要求JSON數據,這類做法不受同源政策限定;服務器收到要求后,將數據放在一個指定名字的回調函數里傳返來。
起首,網頁動態插進去<script>
元素,由它向跨源網址發出要求。
例子:
客服端
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://localhost:3000/test?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
上面代碼經由過程動態增加<script>
元素,向服務器http://localhost:3000
發出要求。注重,該要求的查詢字符串有一個callback
參數,用來指定回調函數的名字,這關於JSONP是必需的。
服務器收到這個要求今後,會將數據放在回調函數的參數位置返回。
JavaScript服務端
var express = require('express');
var app = express();
app.get('/test', function (req, res) {
var cbFunction = req.query.callback
res.send(`${cbFunction}({"ip":"110.110.110.110"})`);
//或許不必那末貧苦直接經由過程express供應的API
/**
* res.jsonp({ip:"110.110.110.110"});
*/
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
上面代碼經由過程express做的簡樸背景,當要求接口時,後端拿到callback
參數然後將其與要返回的數據組合成字符串的情勢返回給客戶端。
因為<script>
元素要求的劇本,直接作為代碼運轉。這時候,只需瀏覽器定義了foo
函數,該函數就會馬上挪用。作為參數的JSON數據被視為JavaScript對象,而不是字符串,因而避免了運用JSON.parse
的步驟。
CORS(跨域資源共享)
CORS有兩種要求 :簡樸要求(simple request)和非簡樸要求(not-so-simple request)只需同時滿足以下兩大前提,就屬於簡樸要求。
要求要領是以下三種要領之一:
- HEAD
- GET
- POST
HTTP的頭信息不超越以下幾種字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
通常不同時滿足上面兩個前提,就屬於非簡樸要求。
瀏覽器對這兩種要求的處置懲罰,是不一樣的。
簡樸要求
客戶端
var xhr = new XMLHttpRequest()
xhr.open('post','http://localhost:3000/test',true)
xhr.onload = function(e){
if(e.currentTarget.status==200){
alert(e.currentTarget.responseText)
}
}
xhr.send()
RequestHeaders要求頭信息
Accept:/*/
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Content-Length:0
Host:localhost:3000
Origin:http://localhost:8020
Referer:http://localhost:8020/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
JavaScript服務端
app.post('/test', function (req, res) {
res.set('Access-Control-Allow-Origin','http://localhost:8020')
res.send({
name:'tom'
})
});
ResponseHeaders
Access-Control-Allow-Origin:http://localhost:8020
Connection:keep-alive
Content-Length:14
Content-Type:application/json; charset=utf-8
Date:Mon, 09 Apr 2018 02:09:05 GMT
ETag:W/"e-v50e5W1R/vD6VVQyxqDA0eSWedA"
X-Powered-By:Express
非簡樸要求
預檢要求
客戶端
var xhr = new XMLHttpRequest()
xhr.open('put','http://localhost:3000/test',true)
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.onload = function(e){
if(e.currentTarget.status==200){
alert(e.currentTarget.responseText)
}
}
xhr.send()
當發送上面的http要求時瀏覽器會先發送一個options範例的http的預檢要求
RequestHeaders要求頭信息
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Access-Control-Request-Headers:x-custom-header
Access-Control-Request-Method:PUT
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8020
Referer:http://localhost:8020/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
JavaScript服務端
//options範例用於CORS非簡樸要求的預檢要求
app.options('/test',function(req,res){
res.set('Access-Control-Allow-Origin','http://localhost:8020') //必需設置
res.set('Access-Control-Allow-Methods','PUT') //必需設置
res.set('Access-Control-Allow-Headers','X-Custom-Header') //假如瀏覽器要求包括Access-Control-Request-Headers字段,則Access-Control-Allow-Headers字段是必需的。
res.send({status:200,msg:'預檢勝利!'})
})
ResponseHeaders
Access-Control-Allow-Headers:X-Custom-Header
Access-Control-Allow-Methods:PUT
Access-Control-Allow-Origin:http://localhost:8020
Connection:keep-alive
Content-Length:38
Content-Type:application/json; charset=utf-8
Date:Mon, 09 Apr 2018 04:08:40 GMT
ETag:W/"26-+1THtR73k4ca8avMcdsJULlJZUs"
X-Powered-By:Express
關於客戶端和服務端字段響應申明能夠在
這裏檢察
一般要乞降回應
一旦服務器經由過程了”預檢”要求,今後每次瀏覽器一般的CORS要求,就都跟簡樸要求一樣,會有一個Origin
頭信息字段。服務器的回應,也都邑有一個Access-Control-Allow-Origin
頭信息字段。
客戶端
RequestHeaders要求頭信息
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Content-Length:0
Host:localhost:3000
Origin:http://localhost:8020
Referer:http://localhost:8020/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
X-Custom-Header:value
上面頭信息的Origin
字段是瀏覽器自動增加的。
JavaScript服務端
app.put('/test', function (req, res) {
res.set('Access-Control-Allow-Origin','http://localhost:8020')
res.send({
name:'tom'
})
});
ResponseHeaders
Access-Control-Allow-Origin:http://localhost:8020
Connection:keep-alive
Content-Length:14
Content-Type:application/json; charset=utf-8
Date:Mon, 09 Apr 2018 04:08:40 GMT
ETag:W/"e-v50e5W1R/vD6VVQyxqDA0eSWedA"
X-Powered-By:Express
上面頭信息中,Access-Control-Allow-Origin
字段是每次回應都一定包括的。