📅  最后修改于: 2023-12-03 14:57:49.233000             🧑  作者: Mango
当我们在页面中动态添加<script>
标签,并且该标签的src
属性指向远程资源时,由于浏览器的同源策略,这个远程资源就无法被读取。
这时候我们可以通过一些技巧来绕过这个限制,使得在同源限制下仍然能够读取到远程资源。
JSONP是一种常见的跨域解决方案之一。在使用JSONP时,我们会在页面中动态添加一个<script>
标签,用来请求远程服务器上的数据。
由于浏览器对<script>
标签的跨域限制比较宽松,所以即使这个远程服务器与当前页面不在同一个域下,浏览器仍然会成功执行该标签中的代码。
通常,JSONP请求会通过callback参数来传递回调函数的名字,在请求的响应中将该函数名和需要传递回来的数据拼接成一个类似于callback(data)
的字符串。
在页面中,我们会事先定义一个回调函数,并将其传递给远程服务器。当远程服务器响应时,它会将需要传递的数据以及回调函数名一起返回。这样,浏览器就会在页面中调用该回调函数,并且返回服务器返回的数据。
下面是一个JSONP请求的基本代码:
<script>
function jsonp(url, callback) {
var script = document.createElement('script');
script.src = url + '?callback=' + callback;
document.body.appendChild(script);
}
function handleResponse(err, data) {
if (err) {
console.error(err);
}
else {
console.log(data);
}
}
jsonp('http://remote.server.com/api/data', 'handleResponse');
</script>
CORS(Cross-Origin Resource Sharing)是另一种常见的跨域解决方案。与JSONP不同,CORS需要在远程服务器的响应头中添加Access-Control-Allow-Origin
字段来授权跨域请求。
在使用CORS时,我们会发起一个XMLHttpRequest请求,并将withCredentials
参数设置为true。如果响应头中包含所需的授权信息,则该请求能够成功响应。
下面是一个使用CORS发起请求的基本代码:
<script>
function cors(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, xhr.responseText);
}
else {
callback(new Error(xhr.statusText));
}
}
};
xhr.withCredentials = true;
xhr.open('GET', url, true);
xhr.send();
}
function handleResponse(err, data) {
if (err) {
console.error(err);
}
else {
console.log(data);
}
}
cors('http://remote.server.com/api/data', handleResponse);
</script>
如果上述两种方法都无法解决问题,我们可以考虑使用代理。在使用代理时,我们会在本地部署一个服务器,用来转发请求并将响应返回到页面。
通过这种方式,我们可以让远程服务器将响应数据发送到我们所控制的服务器上,并将其转发回页面。这样,我们就能够在同源限制下访问远程资源了。
下面是一个使用代理发起请求的基本代码:
<script>
function proxy(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, xhr.responseText);
}
else {
callback(new Error(xhr.statusText));
}
}
};
xhr.open('GET', '/api/proxy?url=' + encodeURIComponent(url), true);
xhr.send();
}
function handleResponse(err, data) {
if (err) {
console.error(err);
}
else {
console.log(data);
}
}
proxy('http://remote.server.com/api/data', handleResponse);
</script>
跨域请求阻止同源策略不允许读取节点js中的远程资源是一个常见的问题。
我们可以通过使用JSONP、CORS或代理来绕过这个限制,以便在同源限制下访问远程资源。
我们希望这篇文章能够帮助你更好地了解跨域请求的解决方案,并在实践中发挥作用。