深刻跨域問題(1) - 初識 CORS 跨域資源共享;javascript
深刻跨域問題(2) - 利用 CORS 解決跨域(本篇)html
在閱讀這篇文章以前,讀讀第一篇文章,效果會更好!!!回答上一篇文章的問題:node
application/x-www-form-urlencoded
。Content-Type
爲 application/json
。並不是上文中的三種狀況,text/plain
,multipart/form-data
,application/x-www-form-urlencoded
。第三點,是最重要的一點,也是常常出錯的一點,記住觸發預請求三種狀況 !!!jquery
模擬客戶端請求:ios
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ajax測試</title>
</head>
<body>
<script src="./node_modules/jquery/dist/jquery.min.js"></script>
<script> $.ajax({ url: "http://localhost:3000", type: "get", success: function (result) { console.log(result); }, error: function (msg) { console.log(msg); } }) </script>
</body>
</html>
複製代碼
後文,將再也不粘貼 html
代碼,jquery
也能夠用 npm install jquery
下載。ajax
模擬服務器響應,新建 app.js 文件,粘貼並運行 :npm
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.end("true");
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
複製代碼
好了,如今雙擊打開 html 文件,就成了:json
很明顯,這就是跨域報錯。
在上述兩個例子中,咱們說到,POST 和 GET 方法,均可以實現,非預請求。
關鍵代碼:設置一條 響應首部字段,容許 CORS 跨域資源共享:
response.writeHead(200, {
'Access-Control-Allow-Origin': '*
}
複製代碼
這裏,咱們設置爲,全部客戶端均可以訪問。
完整代碼:
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*' // 關鍵代碼
});
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*' // 關鍵代碼
});
response.end("true");
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
複製代碼
前端測試代碼:
$.ajax({
url: "http://localhost:3000",
type: "get",
success: function (result) {
console.log(result);
},
error: function (msg) {
console.log(msg);
}
})
var data = { name: 'BruceLee', password: '123456' };
$.ajax({
url: "http://localhost:3000",
type: "post",
data: JSON.stringify(data),
success: function (result) {
console.log(result);
},
error: function (msg) {
console.log(msg);
}
})
複製代碼
執行結果:
處理 非預請求 就是這麼簡單,只須要在後臺設置,一條 響應首部字段 便可。
注意:咱們使用 POST 方法時,Jquery 默認使用的 Content-Type: application/x-www-form-urlencoded
,因此不會觸發預請求 !!!
事實上,不單單是 Jquery ,axios 等封裝 Ajax 的庫,都默認採用 Content-Type: application/x-www-form-urlencoded
!!!
不單單是 POST ,全部 預請求 的處理方式都同樣。
POST 方法在設置 contentType
爲 application/json
時會觸發預請求。
前端測試代碼:
var data = { name: 'BruceLee', password: '123456' };
$.ajax({
url: "http://localhost:3000",
type: "post",
data: JSON.stringify(data),
contentType: 'application/json;charset=utf-8',
success: function (result) {
console.log(result);
},
error: function (msg) {
console.log(msg);
}
})
複製代碼
注意,這裏的 contentType
已經修改成 application/json
,這種狀況是會觸發 預請求 的 ! ! !
node 服務端代碼:
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end( JSON.stringify({state: true}) );
}
if (request.method === 'OPTIONS') {
response.end( JSON.stringify({state: true}) );
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
複製代碼
在這裏,咱們增長了處理 OPTIONS 方法的邏輯。
測試結果:
很明顯,咱們在 OPTIONS 方法內部沒有設置 CORS 響應首部字段 ,因此出現跨域錯誤;
修改代碼,關鍵代碼:
if (request.method === 'OPTIONS') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*', // 設置 optins 方法容許全部服務器訪問
'Access-Control-Allow-Methods': '*', // 容許訪問 POST PUT DELETE 等全部方法
});
response.end( JSON.stringify({state: true}) );
}
複製代碼
在 node 代碼中,咱們增長對 OPTIONS 的處理,而且設置容許訪問, POST 方法。
修改代碼後,重啓服務器,並刷新 html 頁面,結果爲:
在這裏,仍然是有問題,按照報錯描述,咱們應該設置 Access-Control-Allow-Headers
響應首部字段 。
關鍵代碼:
if (request.method === 'OPTIONS') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*', // 設置 optins 方法容許全部服務器訪問
'Access-Control-Allow-Methods': '*', // 容許訪問路徑 '/' POST等全部方法
'Access-Control-Allow-Headers': 'Content-Type', // 容許類 Content-Type 頭部
});
response.end( JSON.stringify({state: true}) );
}
複製代碼
咱們須要設置,容許使用頭部爲 Content-Type
的內容訪問。
完整代碼:
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end( JSON.stringify({state: true}) );
}
if (request.method === 'OPTIONS') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*', // 設置 optins 方法容許全部服務器訪問
'Access-Control-Allow-Methods': '*', // 容許訪問路徑 '/' POST等全部方法
'Access-Control-Allow-Headers': 'Content-Type', // 容許類 Content-Type 頭部
});
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
複製代碼
執行結果:
預請求
POST 請求
這樣就完成,對 預請求 的處理。如今你能夠狠狠地告訴後臺:是你沒有處理 OPTIONS 方法 !!!
好了,到這裏,知道了基礎的 預請求 處理的解決辦法了。
使用 CORS 跨域資源共享,是須要分紅 預請求 與 非預請求 處理的。
非預請求,在服務器內,只須要簡單設置:
'Access-Control-Allow-Origin': '* 複製代碼
預請求,在服務器內,至少要設置三個 響應首部字段:
'Access-Control-Allow-Origin': ?,
'Access-Control-Allow-Methods': ?,
'Access-Control-Allow-Headers': 'Content-Type',
複製代碼
前端使用 content-Type: application/json
的時候,必須注意這是 預請求 ,後端須要處理 OPTIONS 方法
祝你們編碼愉快,喜歡的話點個贊再走唄!!!