CORS-跨域资源共享 解决跨域问题
1.什么是跨域?
a.test.com 和 b.test.com 是兩個不同的域,而處于安全機制考慮,JS只能訪問與所在頁面同一個域(相同協議、域名、端口)的內容,但是我們在項目開發時,經常遇到一個頁面的js代碼,需要去訪問另一個服務器上的接口,包括GET,POST,PUT等不同形式請求,這就出現了跨域問題。
2.解決跨域的幾種方法。
通過實際項目中涉及到的和網上看到別人用過的,總結一下大概有以下幾種方法:
1).?document.domain
在主域相同的時候才能使用。
2).?iframe
這種方式已經很少見到了,很不優雅,很難控制。
3).?JSONP
這種方式應該是有一定的能力處理跨域請求的,但是缺點也十分明顯,因為原理是動態創建script標簽,通過回調來獲取數據,那么就是說它只能處理GET請求。而且對于請求失敗的error處理也不好。
4). web socket
H5 新增加的一種瀏覽器的API。只有在支持web socket協議的服務器上才能正常工作。
var url='ws://www.baidu.com'; ?//http->ws; https->wss
if ("WebSocket" in window) {
console.log("WebSocket works...");
var ws = new WebSocket(url);
ws.onopen = function() {
// Web Socket is connected, send data using send()
var msg = '{"key": "test","group": "A"}';
ws.send(msg);
console.log("Request to open a connection... Message sent...");
};
ws.onmessage = function(evt) {
var data = evt.data;
// console.log("Message received, and it's...");
console.log(data);
};
ws.onclose = function(e) {
// websocket is closed.
console.log("Connection is closed...");
//console.log(e);
connect();
};
ws.onerror = function(e){
// websocket is error.
console.log("Connection is error...");
//console.log(e);
}
} else {
// The browser doesn't support WebSocket
console.warn("WebSocket NOT supported by your Browser...");
}
5).CORS
這么多解決方法中目前最方便有效的就是這種,CORS。
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing),它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源的限制。
6).在開發中經常用來解決本地跨域的一種方法是配置nginx,再轉發到線上或者測試服務器。不知道這種算不算一種方法。
http?{? ?
server?{? ? ? ? ?
listen? ? ? ? ? 80;? ? ? ? ?
server_name? ? ? w.dev.test.com?w.test.com; ? ? ? ??
? ?location?~?^/(api|action|avatar|financing|files)/{? ? ? ? ? ? ?
if?($host?=?"w.test.com"){? ? ? ? ? ? ? ?
proxy_pass?"https://www.test.com";? ? ? ? ? ? ?
}? ? ? ? ? ? ?
if?($host?=?"w.dev.test.com"){? ? ? ? ? ? ?
proxy_pass?"http://dev.test.com";? ? ? ? ? ? ?
}? ? ? ? ?
}? ? ? ? ?
location?/{ ...?}
}
}
3.CORS 詳解:
CORS實現起來很簡單,但是需要瀏覽器和服務器同時支持,也就是說服務器需要配置允許你跨域請求,瀏覽器也需要支持你能夠跨域去請求資源。目前大部分瀏覽器都能夠支持。
1). 服務器端配置:
Access-Control-Allow-Origin: <origin> | * // 授權的源控制
Access-Control-Max-Age: <delta-seconds> // 授權的時間
Access-Control-Allow-Credentials: true | false // 控制是否開啟與Ajax的Cookie提交方式
Access-Control-Allow-Methods: <method>[, <method>]* // 允許請求的HTTP Method
Access-Control-Allow-Headers: <field-name>[, <field-name>]* // 控制哪些header能發送真正的請求
response headers中與CORS請求相關的字段,都以Access-Control-開頭。
(1)Access-Control-Allow-Origin?該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*,表示接受任意域名的請求。
(2)Access-Control-Allow-Credentials?該字段可選。它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。
(3)Access-Control-Allow-Headers?如果瀏覽器請求包括Access-Control-Request-Headers字段,則Access-Control-Allow-Headers字段是必需的。它也是一個逗號分隔的字符串,表明服務器支持的所有頭信息字段。
(4)Access-Control-Allow-Methods?該字段必需,它的值是逗號分隔的一個字符串,表明服務器支持的所有跨域請求的方法。注意,返回的是所有支持的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預檢"請求。測試中發現,如果瀏覽器請求中沒有Access-Control-Request-Method字段,此字段可不設置。
(5)Access-Control-Max-Age?該字段可選,用來指定本次預檢請求的有效期,單位為秒。
***需要注意的是,如果要發送Cookie,Access-Control-Allow-Origin就不能設為星號,必須指定明確的、與請求網頁一致的域名。同時,Cookie依然遵循同源政策,只有用服務器域名設置的Cookie才會上傳,其他域名的Cookie并不會上傳,且(跨源)原網頁代碼中的document.cookie也無法讀取服務器域名下的Cookie。
2). 前端
如果前端不做任何特殊設置,正常請求跨域的域名接口是可以的,但是只能是GET,且不帶有cookie。
如果想要在request headers中帶有cookie就要進行特殊的設置。
jQuery:
$.ajax("www.cros.com/api/data", {
type: "GET",
xhrFields: {
withCredentials: true
},
success: function(data, status, xhr) {}
});
angularJs:
$http.post(url, {withCredentials: true, ...})
// 或者
$http({withCredentials: true, ...}).post(...)
// 或者
.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}
經過測試法相,jQuery中無論是GET請求還是POST請求,在請求頭中是不會加上Access-Control-Request-Headers字段的,也就是說這樣jQuery不需要服務器設置Access-Control-Allow-Headers。可以看到只有Host顯示是跨域請求,其他的和同域沒什么區別。
但是在angularJs中是不一樣的,GET請求基本差不多
但是POST請求是會加上?Access-Control-Allow-Methods和Access-Control-Allow-Headers。
這時如果服務器沒有設置Access-Control-Allow-Headers,就會請求失敗。
?
?
參考:http://www.cnblogs.com/JChen666/p/3399951.html
http://www.ruanyifeng.com/blog/2016/04/cors.html
??https://my.oschina.net/blogshi/blog/303758
轉載于:https://www.cnblogs.com/isnan/p/6101294.html
總結
以上是生活随笔為你收集整理的CORS-跨域资源共享 解决跨域问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PYTHON学习笔记-DAY-16
- 下一篇: 手机qq网名怎么改不了