Node.js踩坑之旅(四)— 跨域请求的问题(CORS)

通过最近的学习发现,那些技术书籍未必都那么严谨,有些或多或少都有些问题。特别是书上的示例代码,最好都理解后自己再写一遍。说不定就能碰到书上没有说到的问题。

我今天看到了http模块。书上有一个关于Ajax请求数据的例子,我看完之后也写了一遍,却发现书上挖了个大坑,或者说书上说的并不详细。

我写的代码是这样的:

  1. 网页代码:
<!DOCTYPE html>
<html>
	<head>
		<title>Test</title>
		<meta charset="utf-8">
		<script type="text/javascript">
			function clickHandler(){
				let xhr = new XMLHttpRequest();
				xhr.open("GET", "http://localhost:2000/", true);
				xhr.onreadystatechange = ()=>{
					if(xhr.readyState == 4){
						if(xhr.status == 200){
							document.getElementById('test').innerHTML = xhr.responseText;
							console.log(xhr.responseText);
						}
					}
				}
				xhr.send();
			}
		</script>
	</head>
	<body>
		<button onclick="clickHandler()">Ajax获取数据</button>
		<div id="test"></div>
	</body>
</html>

2.服务器端代码

let http = require('http');
let httpServer = http.createServer();
httpServer.on('request', (req,res)=>{
    console.log(req.headers);
    res.writeHead(200,{'Content-Type': "text/plain", 'Access-Control-Allow-Origin': 'http://localhost'});
    res.write('Hello World');
    res.end();
});
//监听2000端口
httpServer.listen(2000);
httpServer.on('listening',()=>{
    console.log('服务器开始监听');
});

但是当我打开页面,点击网页上的按钮时。浏览器的控制台却打印出了这样的错误。

在这里插入图片描述

错误内容是

test.html:1 Access to XMLHttpRequest at ‘http://localhost:2000/’ from origin ‘null’ has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header has a value ‘http://localhost’ that is not equal to the supplied origin.

这个时候我非常奇怪,重新看书,觉得自己写的代码与书上的代码没有什么逻辑上的差异啊,怎么会出错?

由于报错内容有关CORS,我就去查了一下有关信息。我得知将响应头的Access-Control-Allow-Origin属性的值设为*之后将会允许所有外域访问。于是我抱着试一试的心态把代码修改成下面的样子

let http = require('http');
let httpServer = http.createServer();
httpServer.on('request', (req,res)=>{
    console.log(req.headers);
    res.writeHead(200,{'Content-Type': "text/plain", 'Access-Control-Allow-Origin': '*'});
    res.write('Hello World');
    res.end();
});
//监听2000端口
httpServer.listen(2000);
httpServer.on('listening',()=>{
    console.log('服务器开始监听');
});

结果还真的是不报错了,并且成功的返回了数据。

在这里插入图片描述

这也证实了我的猜想和错误提示–问题的确与跨域请求有关。

这个时候,我又注意到错误信息里的一句话 “from origin ‘null’ has been blocked by CORS policy”

origin怎么会为null呢?
而我一开始为响应头的Access-Control-Allow-Origin属性设置的是http://localhost。难道我把Access-Control-Allow-Origin属性设置为"null"也可以?

let http = require('http');
let httpServer = http.createServer();
httpServer.on('request', (req,res)=>{
    console.log(req.headers);
    res.writeHead(200,{'Content-Type': "text/plain", 'Access-Control-Allow-Origin': 'null'});
    res.write('Hello World');
    res.end();
});
//监听2000端口
httpServer.listen(2000);
httpServer.on('listening',()=>{
    console.log('服务器开始监听');
});

果然,把Access-Control-Allow-Origin属性设置为"null"之后,网页的Ajax操作也一样是正常的。那么现在的问题就是,为什么页面发出的请求头的origin属性会是null

我查了MDN中关于请求头中origin属性的描述

origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

然后又看到了stackoverflow上的一个回答里的一句话

However, file:// URLs produce a null Origin which can’t be authorized via echo-back.

原来是这样,我所写的那个页面是直接在本地打开,并不是从哪个服务器获得,于是也就不存在所谓的“源站”。所以origin属性就会是'null'

换句话说,如果你的页面的URL是以 “file://” 开头的,那么这个页面的所发出的请求头的origin属性的值就是'null'

猜你喜欢

转载自blog.csdn.net/hjc256/article/details/86755623