Để xử lý vấn đề CORS (Cross-Origin Resource Sharing) trong webman, bạn cần thực hiện một số bước tùy thuộc vào việc có tắt tính năng tự động định tuyến hay không.
Tắt tự động định tuyến
Nếu bạn muốn tắt tự động định tuyến, hãy sử dụng lệnh sau:
Route::disableDefaultRoute();
Cấu hình Middleware cho CORS
Nếu không tắt tự động định tuyến, bạn chỉ cần gắn middleware CORS vào các đường dẫn cụ thể. Nếu đã tắt tự động định tuyến, bạn cần cấu hình middleware trong file config/middleware.php:
return [
'' => [
\app\middleware\CORSHandler::class, // Xử lý yêu cầu CORS
]
];
Middleware CORS
Dưới đây là mã nguồn của middleware CORS:
<?php
namespace app\middleware;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class CORSHandler implements MiddlewareInterface
{
public function process(Request $request, callable $next): Response
{
// Nếu là yêu cầu OPTIONS, trả về một phản hồi trống, ngược lại tiếp tục xử lý
$response = strtoupper($request->method()) === 'OPTIONS' ? response('', 204) : $next($request);
// Thêm các header CORS vào phản hồi
$response->withHeaders([
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
]);
return $response;
}
}
Gắn Middleware vào Nhóm Đường Dẫn
Nếu bạn đã tắt tự động định tuyến, bạn cần cấu hình nhóm đường dẫn và gắn middleware như sau:
Route::group('/open', function () {
Route::get('/test', [app\controller\Web\TestController::class, 'index'])->name('Kiểm tra');
Route::post('/uploadPic', [app\controller\Web\IndexController::class, 'uploadPic']); // Tải lên ảnh
Route::post('/uploadFile', [app\controller\Web\IndexController::class, 'uploadFile']); // Tải lên tệp
})->middleware([
\app\middleware\CORSHandler::class,
\app\middleware\ApiLog::class
]);
Cấu Hình Fallback
Trong trường hợp tắt tự động định tuyến, bạn cần thêm cấu hình fallback để xử lý các yêu cầu đến URL không tồn tại:
use app\util\GlobalCode;
use Webman\Route;
use support\Request;
// Trả về thông tin khi yêu cầu đến URL không tồn tại
Route::fallback(function (Request $request) {
$response = strtoupper($request->method()) === 'OPTIONS' ? response('', 204) : returnJson([GlobalCode::CODE => GlobalCode::NOT_FOUND, GlobalCode::MSG => '404 not found', GlobalCode::DATA => null]);
$response->withHeaders([
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => "*",
'Access-Control-Allow-Methods' => '*',
'Access-Control-Allow-Headers' => '*',
]);
return $response;
});
// Tắt tự động định tuyến
Route::disableDefaultRoute();
// Trang chủ
Route::get('/', function ($request) {
return view('index/view');
});
// Nhóm đường dẫn cho API có quyền
Route::group('/open', function () {
Route::get('/test', [app\controller\Web\TestController::class, 'index'])->name('Kiểm tra');
Route::post('/uploadPic', [app\controller\Web\IndexController::class, 'uploadPic']); // Tải lên ảnh
Route::post('/uploadFile', [app\controller\Web\IndexController::class, 'uploadFile']); // Tải lên tệp
})->middleware([
\app\middleware\CORSHandler::class,
\app\middleware\ApiLog::class
]);
if (!function_exists('returnJson')) {
function returnJson($data = null, int $status = 200, array $headers = ['Content-Type' => 'application/json'], int $options = JSON_UNESCAPED_UNICODE): Response
{
return new Response($status, $headers, json_encode($data, $options));
}
}