浏览器没有为跨源请求设置源 header?

Browser not setting the origin header for cross origin requests?

我有一个简单的 index.html 文件。此 html 正在从 localhost:3000

加载
<body>
    <h1>Some app</h1>
    <script src="http://localhost:3005/script.js"></script>
</body>

script.js 设置为从另一个来源加载:localhost:3005.

根据我的理解,浏览器应该拦截请求并向其添加 origin header - 并发出 preflight 请求localhost:3005服务器检查是否允许localhost:3000

但我没有 origin。浏览器好像没有加原点header。 这是负责提供 script.js 文件 (localhost:3005) 的服务器。我正在使用 cors module.

const app = express()

const whitelist = ["http://localhost:3001"]
const corsOptions = {
    origin: function(origin, callback) {
        console.log("origin is: ", origin);      //undefined -- why is undefined??

        if (whitelist.indexOf(origin) !== -1) {
            callback(null, true)
        }
        else {
            callback(new Error('Not allowed by CORS'))
        }
    }
}

app.use(cors(corsOptions), express.static(__dirname))
app.listen(3005, () => {
    console.log("server listening on port 3005")
})

我的实际目标是 white-list 只有 localhost:3000 要求我的 script.js

我输入 localhost:3001 只是为了测试我是否真的遇到了 cors 错误——它应该是。

但我什至不知道来源 - 是什么原因造成的? 我在 Firefox 和 Chrome 中都遇到了相同的行为。我误解了这个洞的过程吗?谢谢:)

编辑:也许看到请求有帮助

我认为您可能误解了 CORS 的目的。它使服务器能够 opt-in 处理某些类型的请求,否则这些请求在浏览器的同源策略下是不允许的。它没有提供一种机制来禁止以前允许的请求。

同源策略一直允许在 <script> 标签的 src 中执行来自外国的脚本,因此 CORS 根本不适用。这就是请求中没有 header 的原因。

My actual goal is to white-list only localhost:3000 for asking for my script.js.

你不能为此使用 CORS。事实上,你可能根本做不到。我会退后一步,问你为什么要那样做。如果您正在尝试保护私有数据,那么可能需要某种身份验证机制(令牌、cookie 等)。

对于可能遇到此问题的其他人,这里是 Kevin Christopher Henry 上面接受的答案的实际演示。

下面的第一个代码片段从域 www.w3schools.com 请求一个 script(一个带有 src URL 的 .js 文件)(并自动执行它也取决于请求的成功,但这在这里并不重要)。这里需要注意两点:

  1. 此脚本请求是针对不同的域 (www.w3schools.com) 而不是它的来源
  2. 这 运行 成功了。

$.ajax({
  url: 'https://www.w3schools.com/lib/w3codecolor.js',
  dataType: "script",
  success: function(data, status) {
    console.log('Result:', status)
  },
  error: function(err, status) {
    console.log('Error:', error);
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

下面的第二个代码片段向特定 route/page 请求 URL (https://www.w3schools.com/bootstrap)来自域 www.w3schools.com 使用 XHR 。这是向 API 端点发出请求时将使用的内容。 这是CORS管辖的地方。这里要注意两点:

  1. 此请求是针对不同的域 (www.w3schools.com) 而不是它的来源
  2. 这会失败,因为现代浏览器默认限制 cross-origin HTTP 请求 (see more)。现在解决这个问题的唯一方法是在 www.w3schools.com 域上配置 CORS 以接受来自其域外的 XHR 请求。

$.ajax({
  url: 'https://www.w3schools.com/bootstrap',
  success: function(data, status) {
    console.log('Result:', status)
  },
  error: function(err, status) {
    console.log('Error:', err);
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

这里的错误不明确。要查看实际的 CORS 错误,请打开 Web Developers Console,您应该会看到类似

的内容
"Access to XMLHttpRequest at 'https://www.w3schools.com/bootstrap' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

现在错误显示 "from origin 'null'" 的原因是因为这些代码片段可能 运行 来自甚至没有设置请求的沙盒环境 header Origin到“https://whosebug.com”。

然而,如果 Origin 实际设置为“https://whosebug.com”,结果将是相同的。随意将上述脚本复制粘贴到 Web 开发者控制台并尝试一下。