請教各位大大:
我用 Node.JS寫了一個 http server:
const http = require('http');
const pid = process.pid;
let url;
http.createServer((req, res) => {
url = req.url;
console.log(`request from ${url}`);
res.end(`Hello`);
}).listen(8080, () => {
console.log(`Started`);
});
用瀏覽器 http://localhost:8080/ 沒有問題,可以看到 Hello在網頁上。
在 html用 javascript寫:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script>
fetch('http://localhost:8080/',{mode: 'no-cors'})
.then(res => console.log(res))
</script>
</body>
</html>
要如何抓到這個 Hello呢?
backend
const http = require('http');
const fs = require('fs');
const port = process.env.PORT || 3000;
let url = '';
http.createServer((req, res) => {
({ url } = req);
console.log(`request from ${url}`);
switch (url) {
case '/': {
const htmlFile = fs.readFileSync('./index.html', { encoding: 'utf-8'});
res.writeHead(200,{'Content-Type':'text/html'});
res.write(htmlFile);
res.end();
break;
}
case '/api': {
res.writeHead(200,{'Content-Type':'text/html'});
res.write('hello');
res.end();
break;
}
}
}).listen(port, () => {
console.log(`Server is running on http://127.0.0.1:${port}`);
});
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script>
fetch('http://127.0.0.1:3000/api')
.then(res => res.text())
.then(res => console.log(res))
</script>
<body>
</body>
</html>
這樣
直接測你的code 會發現拿不到 response
https://developer.mozilla.org/en-US/docs/Web/API/Response/type
response type 'opaque': Response for “no-cors” request to cross-origin resource.
真正的原因被過濾掉了XD
意思是不是說:server沒有開放,client不能用no-cors強取? 但 Chrome開發人員工具=>網路=>response 有 hello字樣,又表示其實資料有下來?
謝謝 dragonH超人的程式。抱歉我沒說清楚,我是直接用瀏覽器開啟.html,所以才有同源問題吧!
我看了一下規格,mode用no-cors時,發生非網路錯誤的問題,在javascript端取得的response是過濾過的,以避免資訊洩露。我猜測就是一些header的條件不合之類,但是從javascript端看不出問題(被過濾成格式統一的response),然後開發工具會告訴你沒問題,因為這是內部request/response之後才處理的。
sec開頭那幾個是提供request上下文的標頭,應該是fetch自己送出去的。google一下就知道意思。
我試過,以樓煮的例子,no-cors
加上伺服器端送Access-Control-Allow-Origin: *
標頭似乎也沒用。
no-cors
只是不會跳錯誤,該攔該擋的瀏覽器都會做。直接開html,那跟localhost
或127.0.0.1
就不是同樣site了,所以你會收到Sec-Fetch-Site: cross-site
這個fetch發出來的標頭(這是使用者無法更改的標頭)。
猜測問題發生的原因:通常預設的安全規則是只能request同源(same-site)的資源,但是因為mode設為no-cors
導致內部request/response成功,但還是被安全原則檔下,然後response又被過濾,所以看不到真正的錯誤。
細節要看一下fetch api的規格書會比較清楚,我只簡單瞄了一下。
謝謝 fillano超人!我找到
https://chrome.google.com/webstore/detail/cors-unblock/lfhmikememgdcahcdlaciloancbhjino
這工具可以開關chrome的CORS限制,但不知這是什麼樣的概念?用什麼技術做到的?