24

我正在使用 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)
        }
    }

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

我尝试了许多“Access-Control-Allow-xxx”标头,但没有一个起作用..

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

4

5 回答 5

35

浏览器将 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 apis。

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

于 2019-09-07T13:31:26.777 回答
8

那是因为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');
});

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

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

headers: {
    'content-type': 'application/json',
    'Authorization': 'Client-ID [my-client-id]'
}

它应该可以正常工作。

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

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

另外,根据这个

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

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

127.0.0.1   localhost yourdomain.com

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

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

于 2018-12-08T16:47:21.977 回答
1

我在自己的应用程序中有一些观察结果帮助我解决了这个问题。我有一个节点应用程序作为后端 api 服务和一个 VueJS 构建的前端。我将我的节点应用程序设置为带有允许访问我的节点应用程序的端点列表的 cors。在我将其上传到我的服务器之前,在我的本地机器上工作不会给我任何错误。

这是我的环境 本地环境

  • 节点:12.16.1
  • 操作系统:Windows 10
  • 数据库:MySQL
  • NodeJS 服务器框架:ExpressJS
  • 上传模块:Multer

生产环境

  • 节点:12.19.0
  • 操作系统:Ubuntu 20.0.4
  • 数据库:MySQL
  • NodeJS 服务器框架:ExpressJS
  • 上传模块:Multer
  • nginx

以下是基于我的生产构建应用程序的观察。

  1. 当我上传带有图像 [500kb 及以上] [post or put] 的表单时,出现了 cors 错误,但少于那个,一切都很好。
  2. 如果我使用表单数据向服务器发送数据,我会在我的网络选项卡中看到 2 个请求,即 OPTIONS 和实际请求。
  3. 实际请求失败,但我看到我的内容长度非常高,这使我得出结论,由于客户端发送的大量数据而我的服务器可能限制了我的请求被拒绝。我知道这可能会产生误导,但我所做的解决方案有效,所以即使数据限制是问题,我也不知道为什么会出现 cors 问题。

我的解决方案:在我的 nginx 配置文件中,我client_max_body_size100M. 我相信 nginx 有一个默认的1MB

  1. 打开/etc/nginx/sites-available/your-server-file的地方your-server-file可以像www.example.comdefault
  2. 在 server 块内添加以下行。您可以将其设置为您想要的任何数量,而不是100M.
server {
    client_max_body_size 100M;
    ...
}

  1. 输入sudo systemctl restart nginx重启nginx。
  2. 输入sudo nginx -t以检查更改是否成功。
  3. 如果您正在使用pm2并完成,请重新加载您的应用程序。
于 2020-12-06T02:09:47.840 回答
0

根据这篇文章,我在 linux 中使用了这个命令,并且cross-origin修复了一些 OF(!) 。

google-chrome --disable-web-security --user-data-dir="/tmp/YOUR_TEMPORARY_PATH"

于 2021-07-23T16:05:45.533 回答
0

如果您从前端传递标头,这将不起作用。CORS 策略由浏览器启用。当浏览器没有找到响应的标头时,浏览器会阻止响应。

可能的解决方案:

  1. 您可以传递标头作为响应(如果您有权访问后端或询问 API 提供者)

  2. 您可以设置一个中间件来解决这个问题。

您可以从这里获取信息

于 2021-12-06T06:26:47.097 回答