React+PHP仅POST请求触发CORS策略拦截问题求助
解决POST请求的CORS预检错误问题
你的问题核心在于POST请求触发了浏览器的OPTIONS预检请求,但你的PHP代码没有处理这个请求。当发送带有Content-Type: application/json的POST请求时,浏览器会先发送一个OPTIONS请求来验证服务器是否允许这种跨域操作,而你的当前代码只在业务请求时返回CORS头,OPTIONS请求没有得到正确响应,导致浏览器拦截。
解决方案步骤
1. 优先处理OPTIONS预检请求
在PHP代码最开头添加OPTIONS请求的处理逻辑,直接返回必要的CORS头并终止脚本执行,不需要处理后续的数据库操作:
<?php // 先处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header("Access-Control-Allow-Origin: http://localhost:3000"); header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With, X-Auth-Token, Origin, Application"); http_response_code(200); exit(); } // 下面是你原来的CORS头和业务代码 header("Access-Control-Allow-Origin: http://localhost:3000"); header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With, X-Auth-Token, Origin, Application"); // ... 你的数据库连接和业务逻辑代码 ?>
2. 理解为什么之前GET可行而POST不行
- GET请求属于简单请求(满足特定条件:方法为GET/HEAD/POST,Content-Type为
application/x-www-form-urlencoded等),浏览器不会发送预检请求,直接发送请求并检查响应头,所以你设置的Access-Control-Allow-Origin生效。 - 而你的POST请求带
Content-Type: application/json,属于非简单请求,必须先发送OPTIONS预检请求,确认服务器允许后才会发送实际的POST请求。
3. 额外建议:修复SQL注入风险
你的当前代码直接将用户输入拼接到SQL语句中,存在严重的SQL注入漏洞,建议使用mysqli预处理语句来避免这个问题:
// 替换原来的SQL执行部分 if($password == "Ujebale321!") { // 使用预处理语句 $stmt = $connection->prepare("INSERT INTO `events` (`date`, `time`, `description`, `course_fk`, `year_group_fk`, `type_fk`) VALUES (?, ?, ?, ?, ?, ?)"); // 绑定参数("ssssss"表示6个字符串类型参数) $stmt->bind_param("ssssss", $date, $time, $description, $courseID, $groupID, $typeID); if ($stmt->execute()) { echo "Success"; } else { echo "Error: " . $stmt->error; } $stmt->close(); } else { echo "Wrong password"; }
前端代码小优化
mode: 'cors'是fetch的默认值,可以不用显式声明,去掉也不会影响功能:
const editEvent = async () => { const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ eventID: chosenEvent, courseID: courseID, groupID: groupID, time:time, date: date, description: description, typeID: typeID, password: password}), // 去掉mode: 'cors',默认就是cors模式 }; const response = await fetch(`https://aleksanderblaszkiewicz.pl/kiedykolos/edit_event.php`, requestOptions); // 记得处理响应,比如const data = await response.text(); }
内容的提问来源于stack exchange,提问作者ablaszkiewicz1
相关产品推荐
相关产品推荐

