在 JavaScript 中,fetch 是一个现代的、基于 promise 的 HTTP 客户端,它提供了一个简单的方式来跨域发送请求。然而,由于浏览器的同源策略(Same-Origin Policy),默认情况下,使用 fetch 发起跨域请求时会受到限制。下面,我将详细介绍如何使用 fetch 进行跨域请求。
同源策略与跨域请求
同源策略是浏览器的一个安全机制,它限制了从一个源加载的文档或脚本如何与另一个源的资源进行交互。三个方面的信息不能从一个域中加载另一个域的源(即跨域):
- 域名:如 “example.com” 与 “sub.example.com” 是不同源。
- 协议:如 “http” 与 “https” 是不同源。
- 端口:如果端口不同,也是不同源。
跨域请求方法
尽管同源策略限制了跨域请求,但以下方法可以绕过这些限制:
1. CORS(跨源资源共享)
CORS 是一个安全标准,允许服务器指定哪些外部域(或域段)可以被浏览器允许进行跨域请求。要使用 CORS,服务器需要在响应头中设置 Access-Control-Allow-Origin。
以下是一个简单的例子:
fetch('https://example.com/api/data')
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
如果 https://example.com 的服务器设置了适当的 CORS 响应头,那么上面的代码将正常工作。
2. JSONP(JSON with Padding)
JSONP 是一种较老的跨域请求方法,它利用 <script> 标签没有跨域限制的特性。以下是 JSONP 的一个简单示例:
function handleResponse(response) {
console.log('Received data:', response);
}
var script = document.createElement('script');
script.src = 'https://example.com/api/data?callback=handleResponse';
document.head.appendChild(script);
服务器需要将数据以回调函数的形式返回,例如:
// 服务器端代码
if (req.query.callback) {
res.send(req.query.callback + '(' + JSON.stringify(data) + ')');
}
3. 代理服务器
如果无法控制目标服务器,可以设置一个代理服务器来转发请求。客户端请求代理服务器,代理服务器再将请求转发到目标服务器,并将响应返回给客户端。
以下是一个使用代理服务器的示例:
fetch('http://localhost:3000/forward?url=https://example.com/api/data')
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
服务器端代理代码示例(Node.js):
const express = require('express');
const request = require('request');
const app = express();
app.get('/forward', (req, res) => {
request.get(req.query.url, (error, response, body) => {
res.send(body);
});
});
app.listen(3000, () => {
console.log('Proxy server is running on http://localhost:3000');
});
总结
使用 fetch 进行跨域请求有多种方法,其中 CORS 是最常用的。通过设置服务器端的响应头 Access-Control-Allow-Origin,可以实现简单的跨域请求。对于无法控制目标服务器的情况,可以考虑使用 JSONP 或代理服务器。希望这些信息能帮助你解决跨域请求的问题。
