
本教程深入探讨了Web开发中常见的跨域资源共享(CORS)问题,特别是当JavaScript通过Fetch API请求PHP后端时遇到的挑战。文章详细解释了CORS机制、预检请求(OPTIONS)的处理,并提供了PHP服务器端配置CORS响应头的完整示例代码,指导开发者如何正确配置Access-Control-Allow-Origin、Access-Control-Allow-Methods等,以确保跨域请求成功。
跨域资源共享(Cross-Origin Resource Sharing, CORS)是一种浏览器安全机制,旨在允许网页从不同域(协议、域名或端口)请求资源。由于浏览器的同源策略(Same-Origin Policy)限制,默认情况下,JavaScript只能与同源的服务器进行交互。当前端应用(例如运行在 http://localhost:3000)尝试向不同源的后端API(例如 https://api.example.com)发送请求时,浏览器会触发CORS机制,并要求服务器明确授权该跨域请求。如果服务器未正确配置CORS响应头,浏览器将阻止请求,并抛出“Cross-Origin Request Blocked”错误。
CORS请求主要分为两种类型:
为了正确处理CORS请求,服务器需要在响应中包含一系列Access-Control-*头:
立即学习“PHP免费学习笔记(深入)”;
以下是一个PHP后端正确配置CORS以处理JavaScript跨域请求的示例。该示例着重于处理OPTIONS预检请求,并动态设置Access-Control-Allow-Origin。
<?php
class ControllerCustomapiTest extends Controller {
public function index() {
// 1. 设置Access-Control-Allow-Origin
// 优先使用HTTP_ORIGIN头来确定请求来源,并动态设置允许的来源
// 建议在这里维护一个允许的来源白名单,以增强安全性
if (isset($_SERVER['HTTP_ORIGIN'])) {
$origin = $_SERVER['HTTP_ORIGIN'];
// 示例:可以根据白名单判断是否允许该来源
// $allowedOrigins = ['http://localhost:4200', 'https://your-frontend-domain.com'];
// if (in_array($origin, $allowedOrigins)) {
// header("Access-Control-Allow-Origin: " . $origin);
// } else {
// // 如果来源不在白名单中,可以拒绝请求
// http_response_code(403);
// die('Forbidden Origin');
// }
header("Access-Control-Allow-Origin: " . $origin); // 简化示例:允许任何发送HTTP_ORIGIN的来源
} else {
// 如果没有HTTP_ORIGIN头(通常是同源请求或某些非浏览器请求),
// 可以设置一个默认的允许来源,或者根据实际情况设置为 '*' (谨慎使用)
header("Access-Control-Allow-Origin: *"); // 生产环境请务必替换为具体域名
}
// 2. 设置Access-Control-Allow-Credentials (如果需要发送Cookie或认证头)
header('Access-Control-Allow-Credentials: true');
// 3. 设置Access-Control-Max-Age (缓存预检请求结果,单位:秒)
header('Access-Control-Max-Age: 86400'); // 缓存1天
// 4. 处理预检 OPTIONS 请求
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
// 响应允许的HTTP方法
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header("Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS");
}
// 响应允许的请求头
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
// 预检请求成功,返回204 No Content状态码并终止脚本
http_response_code(204);
die();
}
// 5. 处理实际请求 (GET, POST, PUT, DELETE 等)
// 设置响应内容类型为JSON
header('Content-Type: application/json');
// 构建并发送JSON响应
$response = array('success' => true, 'message' => '数据已成功接收');
echo json_encode($response);
}
}
?>代码解释:
前端JavaScript代码通常不需要为CORS做特殊处理,只需按照常规方式发送请求即可。浏览器会自动处理预检请求和CORS验证。
const url = 'https://opecart9349.000webhostapp.com/unzipper/opencart/index.php?route=customapi/test'; // 替换为你的PHP后端URL
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json', // 触发非简单请求,需要预检
// 'Authorization': 'Bearer your_token_here' // 如果需要发送认证头,服务器也需在Allow-Headers中允许
},
body: JSON.stringify({ name: 'John Doe', age: 30 }) // 示例数据
})
.then(response => {
// 检查HTTP状态码,处理非2xx响应
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});跨域资源共享(CORS)是Web开发中不可避免的一部分。正确理解CORS机制,特别是预检请求的作用,并按照本文提供的PHP后端配置示例,可以有效地解决“Cross-Origin Request Blocked”错误。核心在于服务器端要明确告知浏览器,哪些跨域请求是被允许的,以及允许哪些方法、头和来源。通过细致的配置和严谨的安全考量,可以确保您的Web应用在不同域之间安全、顺畅地通信。
以上就是解决跨域资源共享(CORS)问题:PHP与JavaScript实战教程的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号