POST 到外部 API 会抛出 CORS,但它可以从 Postman 工作

Cri*_*n G 13 javascript node.js imgur cors node-fetch

我正在使用 i mgur api通过节点 js 应用程序上传图像

我正在将图像转换为 base64 字符串并通过 Postman 发送它们效果很好。

node-fetch用来进行api调用。

const fetch = require('node-fetch')
...
async uploadImage(base64image) {
        try {
            const url = 'https://api.imgur.com/3/image'
            const res = await fetch(url,
                {
                    method: 'POST',
                    body: { image: base64image },
                    headers: {
                        'content-type': 'application/json',
                        'Authorization': 'Client-ID [my-client-id]',
                        'Access-Control-Allow-Headers': 'Content-Type, Authorization, Access-Control-Allow-Headers',
                        'Access-Control-Allow-Methods': 'POST',
                    }
                }
            )

            console.log(res)
        } catch(err) {
            console.log(err)
        }
    }
Run Code Online (Sandbox Code Playgroud)

错误:从源“ http://localhost:3000 ”获取“ https://api.imgur.com/3/image ”的访问已被 CORS 策略阻止:请求标头字段Access-Control-Allow-Headers为预检响应中的Access-Control-Allow-Headers 不允许

我试过很多“Access-Control-Allow-xxx”头文件,但都没有奏效。

我认为它一定是我遗漏的一些简单的东西。我已经坚持了几个小时,请帮助我。

Jat*_*pta 26

浏览器将 HTTP 请求限制在与您的网页相同的域中,因此您将无法直接从浏览器点击 imgur api 而不会遇到 CORS 问题。

我正在将图像转换为 base64 字符串并通过 Postman 发送它们效果很好。

这是因为 Postman 不是浏览器,因此不受 CORS 策略的限制。

我试过很多“Access-Control-Allow-xxx”头文件,但都没有奏效。

这些标头必须由服务器作为响应返回 - 在您的情况下由 imgur 服务器返回。你不能在浏览器的请求中设置它们,所以它永远不会工作。

错误:从源“ http://localhost:3000 ”获取“ https://api.imgur.com/3/image ”的访问已被 CORS 策略阻止:请求标头字段 Access-Control-Allow-Headers 为预检响应中的 Access-Control-Allow-Headers 不允许。

您的问题的可能解决方案:

  1. 如果您有权访问后端 api,则可以在服务器上设置“Access-Control-Allow-Origin”标头并让您的应用程序访问 api - 但由于您无法访问 imgur 服务器 - 您可能可以'不要那样做。

  2. 在浏览器中禁用 CORS - 您可以使用如下插件:https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en。这种解决方法应该适合开发。该插件将禁用您的 CORS 设置,您将能够点击 imgur api。

  3. 第三种解决方案是使用代理。您可以使用 express 设置一个小型节点服务器。然后,您将访问您自己的节点服务器,该服务器又将访问 imgur api。由于节点服务器不是浏览器环境,它不会有任何 CORS 问题,您将能够通过这种方式访问​​ imgur API。这也是您能够毫无问题地从 Postman 访问 API 的原因。由于 Postman 不是浏览器环境,因此不受 CORS 策略的限制。

  • Chrome 商店的链接不起作用,但我找到了另一个可以解决问题的扩展。谢谢好先生,您值得投票! (2认同)

Ari*_*rty 7

那是因为Access-Control-Allow-Headers,Access-Control-Allow-Methods是服务器使用的标头。服务器通过中间件附加标头。

现在,想象在启用了 CORS 的服务器(在下面的示例中是一个快速服务器)中,正在设置这种(默认)标头:

app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, Accept');
});
Run Code Online (Sandbox Code Playgroud)

您是Access-Control-Allow-Headers从客户端发送的,服务器将其视为未列入白名单的标头。

因此,在标题中只需使用这些:

headers: {
    'content-type': 'application/json',
    'Authorization': 'Client-ID [my-client-id]'
}
Run Code Online (Sandbox Code Playgroud)

它应该可以正常工作。

顺便说一句,我认为它正在与邮递员合作,因为:

  • 如果您不安装那个微小的邮递员捕获扩展,邮递员将无法设置某些标题。
  • 浏览器安全停止跨源请求。如果您禁用 chrome 安全性,它会很好地执行任何 CORS 请求。

另外,根据这个

我相信这可能是 Chrome 不支持 localhost通过Access-Control-Allow-Origin--参见 Chrome 问题

要让 Chrome 发送Access-Control-Allow-Origin标头,只需将 /etc/hosts 文件中的 localhost 别名为其他域,例如:

127.0.0.1   localhost yourdomain.com
Run Code Online (Sandbox Code Playgroud)

然后,如果您使用yourdomain.com而不是 访问您的脚本localhost,则调用应该会成功。

注意:我认为内容类型不应该是application/json它应该像image/jpeg什么的。或者如果它不起作用,也许不要包含该标题。