【问题标题】:How to fix: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header [duplicate]如何修复:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头 [重复]
【发布时间】:2025-12-12 04:40:01
【问题描述】:

我正在尝试使用 php 后端和 React JS 前端构建一个简单的 API。我为此使用了两个单独的 docker 容器(api.dev.de 和 react.dev.de,因为这是必需的。我使用的是稍微适应的 nginx 代理版本。但是,当我发送每个 React fetch 的请求时() 到服务器,我得到错误:

从 'https://api.dev.de/index.php?read=users' 获取访问权限 源 'https://react.dev.de' 已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

您可以在下面看到我正在尝试提出的请求和 .htaccess 文件。

我已经查找了一些对其他人有用的解决方案,包括 this 我也写入了我的 Dockerfile 的一个(并首先在我的 docker-compose.yml 中启用了这个图像的扩展)。

此外,我挖掘了 this 回答并浏览这些链接到其他文章以积累一些知识,但仍然没有成功......

这是我的代码 sn-ps。

Persons.js:

...

fetch('https://api.dev.de/index.php?read=users', {
      method: 'POST',
      headers: {
        'Authorization': 'Basic ' + btoa("<secretName>:<secretPass>"),
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      }
    })

...

.htaccess:

Authtype Basic
AuthName "Protected section. Only for developers."
AuthUserFile /var/www/html/App/.htpasswd
Require valid-user

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"

Dockerfile 中的配置:

FROM thecodingmachine/php:7.3-v2-apache

...

RUN a2enmod headers

...

在执行函数时,我会得到这些控制台日志:

访问 'https://api.dev.de/index.php?read=users' 从 来源“https://react.dev.de”已被 CORS 政策阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请将 请求模式为“no-cors”以使用 CORS 获取资源 已禁用。

VM2133:1 POST https://api.dev.de/index.php?read=users 网络::ERR_FAILED

但是,当我删除 .htaccess 文件中的所有身份验证配置以及从 Persons.js 文件中删除 AuthorizationContent-Type 部分时,我得到了有效的响应。但我不能只从页面中排除我的授权。

当我构建 React 应用程序并将其粘贴到与 API 相同的 docker 容器中然后调用它时,一切正常。所以我假设它是 docker 容器的配置(如果我错了,请纠正我)。

更新:

从昨天开始,我尝试了不同的方法并想出了最后一个问题。

我的 fetch() 函数现在如下所示:

fetch('https://api.dev.de/index.php?read=users&pass=<password>', {
      method: 'GET',
      headers: {
        'Content-Type': 'multipart/form-data',
        'Accept': 'application/json'
      },
    })

我还更改了我的 .htaccess 文件:

# Enabled in the Dockerfile but still checking if it is enabled.
<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Content-Type "*"
    Header set Access-Control-Accept "*"
    # This should enable the authentication header
    Header set Access-Control-Allow-Credentials "true"
</IfModule>

现在请求有效,但是当我更改 fetch() 函数以发送授权标头 ('Authorization': 'Basic: ' + btoa('&lt;username&gt;:&lt;password&gt;')) 和 .htaccess 时:

Authtype Basic
AuthName "Protected section. Only for developers."
AuthUserFile /var/www/html/App/.htpasswd
Require valid-user

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Content-Type "*"
    Header set Access-Control-Accept "*"
    # This should enable the authentication header
    Header set Access-Control-Allow-Credentials "true"
</IfModule>

我仍然收到错误:

从源“https://react.dev.de”获取“https://api.dev.de/index.php?read=users&pass=crud_restAPI_call”的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

这是因为我的.htaccess的顺序还是我需要修改其他东西?

更新 2:

根据我的研究,我发现了一个类似问题的答案:“预检请求 (OPTIONS),这是我遇到未经授权的 401 的地方。我认为这是因为我读过 OPTIONS 去除了一些标题,包括 Authentication 标头,因此没有它,它无法进行身份验证”。

来源:https://github.com/axios/axios/issues/2076

查看 developer.mozilla.org 指南 (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Sending_a_request_with_credentials_included) 我想始终发送凭据(以使预检请求成功)。

但是,这不起作用...

有人知道为什么不这样做吗?

更新了 fetch() 函数:

fetch('https://api.dev.de/index.php?read=users&pass=<password>', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Authorization': 'Basic: ' + btoa('<secretName>:<secretPass>'),
        'Content-Type': 'multipart/form-data',
        'Accept': 'application/json'
      },
    })

我仍然遇到同样的错误:

从源“https://react.dev.de”获取“https://api.dev.de/index.php?read=users&pass=crud_restAPI_call”的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

【问题讨论】:

  • 在您的 apache 配置中,您需要添加对 OPTIONS 请求的处理。答案和解释见*.com/a/45559433/441757
  • @sideshowbarker 我试过了,但输出没有任何变化。 (sudo nano /etc/apache2/apache2.conf)

标签: reactjs .htaccess docker cors


【解决方案1】:

预检请求与 Docker 无关,它们是与浏览器相关的策略。您正在使用触发预检机制的 HTTP 标头,在您的情况下为“授权”标头,并从您的网站域到 api.dev.de 域进行跨域调用。

您可以read this article 避免预检。

我将只向您的 api 服务器添加一个端点,该端点使用适当的 CORS 相关标头(例如,Access-Control-Allow-Origin)响应所有 OPTIONS 请求

【讨论】:

  • 好的,我明天试试,然后更新这篇文章。谢谢你的解释!
  • 好的,有了你的解释,我有点知道该怎么做了,现在基本的身份验证让我感到困惑。
最近更新 更多