【问题标题】:Fetch: I see the response in the DevTools but Fetch still gives me an "Access-Control-Allow-Origin" issue for GETFetch:我在 DevTools 中看到了响应,但 Fetch 仍然给我一个 GET 的“Access-Control-Allow-Origin”问题
【发布时间】:2018-08-10 22:14:28
【问题描述】:

所以我有一个关于fetchAccess-Control-Allow-Origin 的问题。

我尝试获取一些这样的网站:

fetch('https://localhost/.../api/json')
    .then(blob => blob.json())
    .then(data => console.log("data:", data))
    .catch(err => console.log("err: ", err));

所以在 Chrome 网络选项卡中,我看到显然没有问题。 但是,在 JavaScript 代码中,我遇到了CORS 问题。这怎么可能呢?见:

我尝试添加mode: 'cors' 它没有帮助。我尝试添加mode: 'no-cors',是的,它通过了,但在这种情况下我无法读取答案,我得到Unexpected end of input,而'blob' 变量无论如何都是空的。

如果我使用 PostmanCurl 执行相同的 GET 请求而没有任何选项或标题,它就像一个魅力,我得到了我的回应。

你有什么想法吗? 提前致谢

编辑:由于它正在处理 PostmannCurl,并且由于我可以在 Chrome 调试器中看到响应,我不认为它是另一个问题的重复,其中请求明确地转到外部不允许从其他地方访问的 URL。对吧?

Edit2:它是否可能必须这样做地址:https://localhost 是自签名的,因此没有有效的证书?在 curl 我必须添加 --insecure 标志。

【问题讨论】:

  • “那我该怎么办?”可以做什么。 服务器 必须授权请求,否则浏览器将阻止您的代码看到响应。这就是SOPCORS 的工作原理。
  • @T.J.Crowder 请解释为什么它在PostmanCurl 中工作,为什么我可以在浏览器调试器中看到答案?对我来说似乎不对,而且看起来不像是重复的。
  • 链接问题的答案中已包含这些内容,请务必花时间阅读它们。请注意我在上面的评论 "...否则 浏览器 将阻止您的代码看到响应..." Postman 和 Curl 等不是浏览器。 SOP 是特定于浏览器的东西。
  • @T.J.Crowder 我想知道当我仍然可以在浏览器网络选项卡中看到答案时,保护在哪里(见图)。它不应该返回某种错误吗?如果您仍然可以看到响应但在 JS 中看不到,那么好处在哪里?
  • 所以如果你说的是真的(这对我来说不是很清楚),那么实际上至少有可能获取请求:设置另一个使用 curl 的 api 服务器。然后您将开始联系 api2,它在 api1 上使用 curl 并将数据从 api1 传递回客户端。我会在星期一试试。这将工作 90% 肯定。然后我不明白为什么浏览器在我可以绕过它的情况下首先阻止直接获取。

标签: javascript get cors fetch


【解决方案1】:

正如 T.J. 指出的那样。克劳德,这是在浏览器中不可能做到的。查看相关资源:

但是,不要绝望!有一个解决方法

cURL 服务器解决方法:

我们将使用调用cURL 的节点服务器来绕过限制:

你需要 nodejs 和 npm。

  • 执行npm initnpm i -S express
  • 添加一个api.js 文件。使用以下代码:
    const https = require("https");
    const express = require('express');

    const app = express();

    app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
    });

    app.get('/', function (req, res) {
        const exec = require('child_process').exec;

        exec('curl ' + req.query.url + ' --insecure', function (error, stdout, stderr) {
          console.log('stdout: ' + stdout);
          console.log('stderr: ' + stderr);

          res.json(stdout);

          if (error !== null) {
            console.log('exec error: ' + error);
          }
        });
    });

    app.listen(3000, function () { console.log('listening on port 3000!'); });
  • 通过node api.js运行服务器
  • 现在您可以在您的代码中向localhost:3000 发出请求,在查询参数中添加您要发出get 请求的网址。示例:
    fetch('http://localhost:3000/?url=https://HOST/.../api/json')
      .then(blob => blob.json())
      .then(data => console.log("data:", data))
      .catch(err => console.log("err: ", err));
  • 请求现在按预期工作。尽情享受吧。

【讨论】:

    猜你喜欢
    • 2012-11-08
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2017-06-15
    • 2021-07-23
    • 2015-02-03
    相关资源
    最近更新 更多