Nodejs is not allowed by Access-Control-Allow-Origin.
Nodejs is not allowed by Access-Control-Allow-Origin.
<html>
<head>
<script type=“text/javascript” src=“jquery-1.8.2.js”></script>
<script type=“text/javascript”>
// we will add our javascript code here
$(document).ready(function() {
$.get(‘http://baidu.com’, function(data) {
console.log(data);
});
console.log("Sample of data33:");
});
</script>
</head>
<body>
<!-- we will add our HTML content here -->
<a href="">Link</a>
</body>
</html>
Chrome console: Sample of data33: dd.html:11 XMLHttpRequest cannot load http://baidu.com/. Origin http://192.168.7.14:88 is not allowed by Access-Control-Allow-Origin.
问题描述
在上述HTML代码中,当从本地服务器(例如 http://192.168.7.14:88
)通过AJAX请求访问百度网站时,浏览器抛出了一个跨域错误:
XMLHttpRequest cannot load http://baidu.com/. Origin http://192.168.7.14:88 is not allowed by Access-Control-Allow-Origin.
这是因为浏览器出于安全考虑,不允许从一个源(origin)向另一个不同的源发起跨域请求。如果目标服务器(如百度)没有设置适当的CORS (Cross-Origin Resource Sharing) 头,那么请求就会失败。
解决方案
为了在开发过程中解决这个问题,可以使用Node.js创建一个简单的代理服务器来转发请求。这样,你的前端应用就可以与这个代理服务器通信,而代理服务器再与目标服务器通信。这种方式不会触发跨域限制,因为所有的请求都是在同一源内完成的。
示例代码
首先,确保你已经安装了Node.js和npm。然后,在项目根目录下初始化一个新的Node.js项目并安装必要的依赖:
npm init -y
npm install express http-proxy-middleware
接下来,创建一个名为 server.js
的文件,并添加以下代码:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'http://baidu.com',
changeOrigin: true,
}));
app.listen(8888, () => {
console.log('Server is running on port 8888');
});
这段代码创建了一个Express服务器,它会将所有以 /api
开头的请求代理到 http://baidu.com
。changeOrigin: true
选项使得代理请求看起来像是从目标服务器发起的,这有助于某些需要检查请求来源的应用程序正常工作。
修改HTML代码
修改HTML文件中的AJAX请求,使其指向新的代理服务器:
<html>
<head>
<script type="text/javascript" src="jquery-1.8.2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.get('http://localhost:8888/api', function(data) {
console.log(data);
});
console.log("Sample of data33:");
});
</script>
</head>
<body>
<a href="">Link</a>
</body>
</html>
现在,当你运行Node.js服务器并访问HTML页面时,AJAX请求应该能够成功获取数据,而不受跨域限制的影响。
curl http://baidu.com 就可以,什么区别?
跨域了,浏览器的Same-Origin策略,具体可以google下
遇到这种情况怎么处理呢?我想到的一种:在server端定时curl获取baidu.com,然后brower再用ajax调用自己server端的数据。不过这样很耗服务器资源啊。
这个问题是由于浏览器的同源策略(Same-Origin Policy)限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。具体来说,当您的前端应用试图通过 AJAX 请求从 http://baidu.com
获取数据时,浏览器检查请求的源(这里是 http://192.168.7.14:88
)是否允许访问目标资源的源。因为百度网站没有设置 Access-Control-Allow-Origin
头,所以浏览器拒绝了这个请求。
解决方案
如果您控制服务器端(在这种情况下是百度),可以在响应头中添加 Access-Control-Allow-Origin
允许特定来源的请求。但是,对于外部网站如百度,我们无法直接修改它们的响应头。因此,您可以考虑使用代理服务器来解决这个问题。
使用 Node.js 作为代理服务器
您可以使用 http-proxy-middleware
这个库来创建一个简单的代理服务器,该代理服务器会将请求转发到百度,并在响应头中添加所需的 CORS 头信息。
首先安装必要的库:
npm install express http-proxy-middleware
然后,创建一个简单的 Node.js 服务器:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'http://baidu.com',
changeOrigin: true,
onProxyRes(proxyRes) {
proxyRes.headers['Access-Control-Allow-Origin'] = '*'; // 或者指定您需要的源
}
}));
app.listen(8080, () => {
console.log('Server is running on port 8080');
});
这样,您可以修改前端的 AJAX 请求,让它指向本地服务器:
$.get('http://localhost:8080/api', function(data) {
console.log(data);
});
通过这种方式,您可以绕过同源策略限制,实现跨域请求。