为什么我的 JavaScript 代码收到“请求的资源上不存在'访问控制-允许-源'标头”错误,而 Postman 则没有?

Mod注意:这个问题是关于为什么浏览器上的//etc.受到相同的访问策略限制(你会得到提到CORB或CORS的错误),而Postman不是。这个问题不是关于如何修复“没有'访问控制-允许-起源'...”错误。这是关于它们为什么会发生。XMLHttpRequestfetch

请停止发帖


我正在尝试通过连接到RESTful API内置Flask来使用JavaScript进行授权。但是,当我提出请求时,我收到以下错误:

XMLHttpRequest 无法加载 http://myApiUrl/login。请求的资源上不存在“访问控制-允许-源”标头。因此,不允许访问原点“null”。

我知道 API 或远程资源必须设置标头,但是当我通过 Chrome 扩展程序 Postman 发出请求时,为什么它能正常工作?

这是请求代码:

$.ajax({
  type: 'POST',
  dataType: 'text',
  url: api,
  username: 'user',
  password: 'pass',
  crossDomain: true,
  xhrFields: {
    withCredentials: true,
  },
})
  .done(function (data) {
    console.log('done');
  })
  .fail(function (xhr, textStatus, errorThrown) {
    alert(xhr.responseText);
    alert(textStatus);
  });

答案 1

如果我理解正确,您正在对与您的页面所在的域不同的域进行XMLHttpRequest。因此,浏览器会阻止它,因为它通常出于安全原因允许在同一源中发出请求。当您想要执行跨域请求时,您需要执行一些不同的操作。有关如何实现此目的的教程是使用 CORS

当您使用Postman时,他们不受此政策的限制。引自Cross-Origin XMLHttpRequest

常规网页可以使用 XMLHttpRequest 对象从远程服务器发送和接收数据,但它们受到同源策略的限制。扩展程序没有那么有限。扩展可以与其源外部的远程服务器通信,只要它首先请求跨源权限即可。


答案 2

警告:使用可能会使您的 API/网站容易受到跨站点请求伪造 (CSRF) 攻击。在使用此代码之前,请确保您了解风险Access-Control-Allow-Origin: *

如果您使用的是PHP,则解决起来非常简单。只需在 PHP 页面的开头添加以下脚本即可处理请求:

<?php header('Access-Control-Allow-Origin: *'); ?>

如果您使用的是 Node-red,则必须通过取消注释以下行来允许文件中的 CORSnode-red/settings.js

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 origin: "*",
 methods: "GET,PUT,POST,DELETE"
},

如果您使用的是Flask,则与问题相同;您必须先安装flask-cors

$ pip install -U flask-cors

然后在应用程序中包含 Flask cors。

from flask_cors import CORS

一个简单的应用程序将如下所示:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

有关更多详细信息,可以查看 Flask 文档