前後端互動跨域問題解決方案,跨域資源共享(CORS)
阿新 • • 發佈:2018-12-30
跨域資源共享(CORS)
普通跨域請求:只服務端設定Access-Control-Allow-Origin即可,前端無須設定,若要帶cookie請求:前後端都需要設定。
需注意的是:由於同源策略的限制,所讀取的cookie為跨域請求介面所在域的cookie,而非當前頁。如果想實現當前頁cookie的寫入,可參考下文:七、nginx反向代理中設定proxy_cookie_domain 和 八、NodeJs中介軟體代理中cookieDomainRewrite引數的設定。
目前,所有瀏覽器都支援該功能(IE8+:IE8/9需要使用XDomainRequest物件來支援CORS)),CORS也已經成為主流的跨域解決方案。
1、 前端設定:
1.)原生ajax
// 前端設定是否帶cookie
xhr.withCredentials = true;
示例程式碼:
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest相容 // 前端設定是否帶cookie xhr.withCredentials = true; xhr.open('post', 'http://www.domain2.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };
2.)jQuery ajax
$.ajax({
...
xhrFields: {
withCredentials: true // 前端設定是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外資訊,但不會含cookie
...
});
3.)vue框架
在vue-resource封裝的ajax元件中加入以下程式碼:
Vue.http.options.credentials = true
2、 服務端設定:
若後端設定成功,前端瀏覽器控制檯則不會出現跨域報錯資訊,反之,說明沒設成功。
1.)Java後臺:
/*
* 匯入包:import javax.servlet.http.HttpServletResponse;
* 介面引數中定義:HttpServletResponse response
*/
// 允許跨域訪問的域名:若有埠需寫全(協議+域名+埠),若沒有埠末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");
// 允許前端帶認證cookie:啟用此項後,上面的域名不能為'*',必須指定具體的域名,否則瀏覽器會提示
response.setHeader("Access-Control-Allow-Credentials", "true");
2.)Nodejs後臺示例:
var http = require('http');
var server = http.createServer();
var qs = require('querystring');
server.on('request', function(req, res) {
var postData = '';
// 資料塊接收中
req.addListener('data', function(chunk) {
postData += chunk;
});
// 資料接收完畢
req.addListener('end', function() {
postData = qs.parse(postData);
// 跨域後臺設定
res.writeHead(200, {
'Access-Control-Allow-Credentials': 'true', // 後端允許傳送Cookie
'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允許訪問的域(協議+域名+埠)
/*
* 此處設定的cookie還是domain2的而非domain1,因為後端也不能跨域寫cookie(nginx反向代理可以實現),
* 但只要domain2中寫入一次cookie認證,後面的跨域介面都能從domain2中獲取cookie,從而實現所有的介面都能跨域訪問
*/
'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly的作用是讓js無法讀取cookie
});
res.write(JSON.stringify(postData));
res.end();
});
});
server.listen('8080');
console.log('Server is running at port 8080...');