问题描述
在 Deno 中使用 fetch 发送请求时,如果请求的地址跨域,服务器没有开启CORS(跨域资源共享)策略,会导致请求失败。
例如:
const res = await fetch('https://api.example.com/data');
如果该请求跨域,且服务器没有开启CORS,就会收到如下错误:
FetchError: request to https://api.example.com/data failed, reason: cors
解决方案
1. 使用跨域代理
跨域代理是一种将请求发送到其他域名下的服务器,然后由该服务器代理访问请求的方案。
我们可以使用第三方跨域代理服务来代理请求,例如 crossorigin.me 或 cors-anywhere.herokuapp.com。
例如:
const res = await fetch('https://cors-anywhere.herokuapp.com/https://api.example.com/data');
它会将请求发送至 https://api.example.com/data
并代理回来,从而避免了跨域问题。
2. 在服务器端开启CORS
如果我们有控制权来更改请求的目标服务器,我们可以在目标服务器上配置CORS以允许跨域请求。这要求服务器发回一个特定的 HTTP 头部以授权 JavaScript 代码访问此资源。
CORS 的配置可能因服务器而异,但一般步骤如下:
- 添加
Access-Control-Allow-Origin
HTTP头,指定允许访问该资源的源。例如:Access-Control-Allow-Origin: https://my-website.com
。 - 如果请求指定了非 GET/HEAD/OPTIONS 方法,则应该添加
Access-Control-Allow-Methods
HTTP头,指定允许的 HTTP 方法。例如:Access-Control-Allow-Methods: GET, POST, DELETE, PUT
。 - 如果请求需要授权访问,则应该添加
Access-Control-Allow-Credentials
HTTP头,并将其值设置为 true。 - 如果请求需要将自定义标头包含在内,则服务器应该使用
Access-Control-Allow-Headers
HTTP头显式确认。例如Access-Control-Allow-Headers: authorization,content-type
.
示例代码
以下是使用 expressjs 的 CORS 中间件设置 CORS 的示例代码:
const express = require('express'); const cors = require('cors'); const app = express(); const port = 3000; app.use(cors()); app.get('/data', (req, res) => { // 处理请求逻辑 }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
在上述示例代码中,我们可以看到通过使用 cors()
中间件函数,服务器仅允许来自所有域名的 GET、HEAD 和 POST 请求,如果需要访问其他 HTTP 方法,可以通过添加 methods
和其他选项来配置。
总结
以上介绍了如何解决 Deno 中使用 fetch 出现跨域问题,虽然使用跨域代理可以避免很多问题,但是建议在服务器端上做好 CORS 配置,让客户端请求更加便捷和安全。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b2386aadd4f0e0ffb66d3c