解决 Deno 中使用 fetch 出现跨域问题

问题描述

在 Deno 中使用 fetch 发送请求时,如果请求的地址跨域,服务器没有开启CORS(跨域资源共享)策略,会导致请求失败。

例如:

const res = await fetch('https://api.example.com/data');

如果该请求跨域,且服务器没有开启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 的配置可能因服务器而异,但一般步骤如下:

  1. 添加 Access-Control-Allow-Origin HTTP头,指定允许访问该资源的源。例如:Access-Control-Allow-Origin: https://my-website.com
  2. 如果请求指定了非 GET/HEAD/OPTIONS 方法,则应该添加 Access-Control-Allow-Methods HTTP头,指定允许的 HTTP 方法。例如:Access-Control-Allow-Methods: GET, POST, DELETE, PUT
  3. 如果请求需要授权访问,则应该添加 Access-Control-Allow-Credentials HTTP头,并将其值设置为 true。
  4. 如果请求需要将自定义标头包含在内,则服务器应该使用 Access-Control-Allow-HeadersHTTP头显式确认。例如 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