在 ReactJs 中使用 Axios 发布到 Laravel 后端时,标题中不存在 Access-Control-Allow-Origin

Posted

技术标签:

【中文标题】在 ReactJs 中使用 Axios 发布到 Laravel 后端时,标题中不存在 Access-Control-Allow-Origin【英文标题】:Access-Control-Allow-Origin not present in header when posting using Axios in ReactJs to a Laravel Backend 【发布时间】:2021-11-09 12:48:35 【问题描述】:

我构建了 Laravel API 并托管在 namecheap 上。我已经使用这些属性设置了 handleCORS 文件:

'paths' => ['api/*'],

'allowed_methods' => ['*'],

'allowed_origins' => ['*'],

'allowed_origins_patterns' => ['*'],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,

在前端,我的请求是使用 axios 发出的,唯一的标头集是内容类型:application/json。当服务器在本地主机上时发出请求可以正常工作。但是推到 namecheap 并将前端推到 vercel,我不断收到这个错误:

从源“https://landearn-web.vercel.app”访问“https://landearn.bumasys.com/api/signup”处的 XMLHttpRequest 已被 CORS 政策阻止:对预检请求的响应没有“ t 通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

这些是我的响应标头:

     cache-control: private, no-cache, no-store, must-revalidate, max-age=0
     content-length: 1238
     content-type: text/html
     date: Tue, 14 Sep 2021 09:49:28 GMT
     pragma: no-cache
     server: LiteSpeed
     x-turbo-charged-by: LiteSpeed

问题是我尝试了很多解决方案,使用了具有这些配置的自定义 CORS 中间件:

$headers = [
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'Authorization, Content-Type, X-Auth-Token, Bearer, Origin',
            'Cache-Control' => 'no-cache, private',
            'X-RateLimit-Limit' => '60',
            'X-RateLimit-Remaining' => '59',
        ];
        
        return response('OK', 200, $headers);
        
        if($request->getMethod() == "OPTIONS") 
            // The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return response('OK', 200, $headers);
        

        $response = $next($request);
        foreach($headers as $key => $value)
            $response->header($key, $value);
        return $response;

我什至添加了一个预检中间件,它捕获每个 OPTIONS 请求并向浏览器请求资源发送一个空响应,这里:

public function handle($request, Closure $next )

    if ($request->getMethod() === "OPTIONS") 
        return response('');
    
    return $next($request);

我是否寻求过解决方案,是的,我有过。我不知道为什么会发生这种情况,过去我一直被限制只能使用我当时为我的 API 请求配置的一个 Laravel 应用程序,但是它太聚集了,不足以让我继续使用,有趣的是如果我通过压缩和解压缩将同一个项目复制到另一个域中,我仍然会遇到相同的 CORS 问题,现在真的迷失了如何永久修复这种 CORS 疯狂问题,我真的不能继续这样下去了。

【问题讨论】:

你试过设置成header("Access-Control-Allow-Origin: *"); 我试过了,它没有产生任何结果,我还注意到在发出请求时从客户端制定该规范是无关紧要的,因为它是来自的资源的唯一功能预期响应的位置。 您的项目在哪个服务器上运行?你直接放在nginx或者apache的config里 服务器在 Namecheap 上运行 https://www.namecheap.com/support/knowledgebase/article.aspx/9410/29/how-to-set-up-rules-and-redirects-in-htaccess/ // https://***.com/a/20838470/10828488 【参考方案1】:

我注意到我在研究期间发现并尝试实施的任何先前解决方案都足以处理跨源资源共享问题,但 htaccess 是主要问题。所以我能够在我的服务器根目录中使用正确的 htaccess,如下所示:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %HTTP:Authorization .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%HTTP:Authorization]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %REQUEST_FILENAME !-d
    RewriteCond %REQUEST_URI (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %REQUEST_FILENAME !-d
    RewriteCond %REQUEST_FILENAME !-f
    RewriteRule ^ index.php [L]
</IfModule>

另外,在实现了更改后,我注意到没有必要构建自定义 CORS 文件并更改 App\HTTP\kernel.php 和 App\Providers\RouteServiceProvider.php 中的配置,因此使用当前包Laravel 自带的 \Fruitcake\Cors\HandleCors::class,它足以解决 preflight 中出现 strict-origin-when-cross-origin 错误的问题。但是您需要使用以下值调整 config\cors.php 文件;

'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'], 

    'allowed_origins' => ['*'], /*very necessary, else specify the exact domain prefix or suffix*/

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => ['*'], /*added this to be able to see the response headers*/

    'max_age' => 0,

    'supports_credentials' => false, /*leaving this as false is better for a long life in good health*/

这些是我的一些发现,我觉得它可以在未来对其他人有所帮助。

【讨论】:

以上是关于在 ReactJs 中使用 Axios 发布到 Laravel 后端时,标题中不存在 Access-Control-Allow-Origin的主要内容,如果未能解决你的问题,请参考以下文章

Yelp Api - Axios/ReactJs - 如何编写代码

reactjs-Axios 帖子返回空对象

从 Promise(ReactJS 和 Axios)中提取图像数据

在 ReactJs 中使用 axios 发送 POST 请求时 $_FILES 为空

Axios ReactJS - 无法读取未定义的属性“setState”

Reactjs Axios / Spring Boot 安全性