Laravel & CORS - 创建一个可分发的 JS 小部件 - 通过 XMLHttpRequest 获取数据,被 CORS 阻止 [重复]

Posted

技术标签:

【中文标题】Laravel & CORS - 创建一个可分发的 JS 小部件 - 通过 XMLHttpRequest 获取数据,被 CORS 阻止 [重复]【英文标题】:Laravel & CORS - Creating a distributable JS widget - fetching data via XMLHttpRequest, blocked by CORS [duplicate] 【发布时间】:2020-11-11 23:30:51 【问题描述】:

我相信所有经验丰富的网络开发人员都知道,CORS 可能会很痛苦!您可能已经经历过几次:

从源“https://www.website.com”访问“https://widget.com/widget”的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

当通过 JS 脚本创建 XMLhttprequest 时会创建此错误。调用请求的JS如下:

widget.js

// Create XML HTTP Request
var request = new XMLHttpRequest();

// Open POST request
request.open('POST', 'https://widget.com/widget');

// Set request header for how the request was sent
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

// Set request header for sending data
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');

// Set request header
request.setRequestHeader('Access-Control-Allow-Origin', '*');

// Send request to target
request.send();

// Listen for response
request.onreadystatechange = function() 

    // Finished processing
    if (request.readyState === 4) 
        
        // Check if the request was successful
        if (request.status === 200) 
            
            console.log(request.responseText);

        
    
;

JS 并没有什么特别之处——我相当确信这个问题与 JS 无关。请求被发送到request.open('POST', 'https://widget.com/widget');,这是我知道发生 CORS 错误问题的地方。

目标 URL 是一个 Laravel 运行的 php 服务器,具有非常标准的路由结构。这是该路由的 Laravel/PHP 代码:

// Send widget DOM
Route::post('/widget', function(Request $request) 
    try 
        
        // Widget code

     catch (Exception $e) 
        // Return error
        return json_encode(['message' => $e->getMessage()]);
    
)->middleware('widgetCORS');

如您所见,我创建了一个路由中间件尝试来解决 CORS 错误,请查看此中间件的代码:

namespace App\Http\Middleware;

use Closure;

class WidgetCORS 

    public function handle($request, Closure $next) 
        // Continue with request
        return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
            ->header('Access-Control-Allow-Headers', 'Content-Type, Authorizations');
    


需要注意的是,widget.com调用JS请求时不会发生错误(如预期的那样),但任何其他网站都不起作用。

我希望这是我的 Laravel 配置导致的问题,我真的可以通过一些帮助来解决这个问题!我什至试过 BarryVDH 的中间件,也没有用...

如果需要更多信息,请告诉我。

谢谢!

【问题讨论】:

谢谢@CBroe,我知道预检请求是什么。您能否提供一些关于我如何解决此问题的见解? @CBroe - 您能否提供一些示例代码来说明如何做到这一点? 您没有发布任何内容。不要添加标题说您正在发布 JSON ......并且不要使用 POST 方法。不要加X-Requested-With,不规范。不要从客户端发送Access-Control-Allow-Origin,它是一个 response 标头。如果您自己的 javascript 可以允许自己从任何网站读取数据,那该有多愚蠢? @Quentin - 请求确实发送 JSON 数据,我删除了 request.send(); 的内容以简化问题。感谢您提供有关 X-Requested-With 和 AC-Allow-Origin 的建议。 你的 Route::post('/widget' ...) 使用了 widgetCORS,但是 OPTIONS 动词被发送到 Laravel 服务器。所以你需要在 OPTIONS 路由上设置 Access-Control-Allow-Origin 到 /widget。 【参考方案1】:

因为错误与 preflight CORS 请求有关,我认为您想通过路由 OPTIONS 动词来处理它。比如:

Route::options('/widget', function(Request $request) )->middleware('widgetCORS');

【讨论】:

以上是关于Laravel & CORS - 创建一个可分发的 JS 小部件 - 通过 XMLHttpRequest 获取数据,被 CORS 阻止 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 和 axios 安装在其他子域 CORS 问题上

Laravel API CORS

Laravel - Vue Axios CORS 策略

Laravel Sanctum + Nuxt JS 我无法通过 CORS

本地主机上的 Access-Control-Allow-Origin(Laravel 和 Vue)CORS CORS 错误

Angular + Laravel 项目的 CORS 问题