Resolving CORS withCredentials Issues in ThinkPHP 5.1
This guide explains how to resolve CORS withCredentials errors in ThinkPHP 5.1 by configuring Axios on the frontend, setting appropriate Access‑Control headers on the backend, creating a CrossDomain middleware, and handling preflight OPTIONS requests for methods like DELETE and PUT.
Cross‑origin resource sharing (CORS) is a browser security feature; this article focuses on solving CORS issues in ThinkPHP 5.1.
In the frontend, the Axios instance is created with withCredentials: true so that cookies are sent with cross‑origin requests.
withCredentials: true // 跨域请求时发送cookie
// 创建一个axios
const service = axios.create({
baseURL: URL ,
withCredentials: true, // 跨域请求时发送cookie
timeout: 5000 // request timeout
})On the backend, a simple header configuration such as header("Access-Control-Allow-Origin: *") leads to a CORS error because the wildcard origin is not allowed when credentials are included.
header("Access-Control-Allow-Origin: *");The browser reports: Access to XMLHttpRequest at 'http://store.ink/admin/me?sid=…' from origin 'http://vue-admin-web.ink' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Therefore, when withCredentials is set to true, the Access-Control-Allow-Origin header must echo the request's origin instead of '*'.
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
header("Access-Control-Allow-Origin: $origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Max-Age: 1728000');If you still want to allow any origin, you can keep the wildcard but must also omit the credentials flag; the example below shows the wildcard configuration.
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Max-Age: 1728000');To apply the correct headers automatically, a middleware named CrossDomain is created.
<?php
namespace app\http\middleware;
use think\Response;
class CrossDomain
{
public function handle($request, \Closure $next)
{
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
header("Access-Control-Allow-Origin: $origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Max-Age: 1728000');
return $next($request);
}
}The middleware is attached to the route group in router.php:
Route::group('', function () {
// ... define routes here ...
})->middleware(['CrossDomain']);Because browsers send a pre‑flight OPTIONS request for methods like DELETE and PUT, the route may not be matched and the middleware might not run. To handle this, an exception renderer is added that also sets the CORS headers.
public function render(Exception $e)
{
// Handle CORS in exception
$origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
header("Access-Control-Allow-Origin: $origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
header('Access-Control-Max-Age: 1728000');
$type = request()->isAjax() ? 'json' : "html";
$response = \think\response\Json::create([], $type, 200, []);
return $response; // must return a response, not throw
}With these configurations, CORS requests that include credentials work correctly in ThinkPHP 5.1.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
