React应用调用fetch请求PHP页面时遭遇CORS错误求助
我来帮你拆解这个问题,本质都是你的PHP接口没配置正确的跨域响应头导致的,咱们一步步理清楚:
为啥本地加cors-anywhere能行,不加就不行?
浏览器有个同源策略,本地开发时你的React app一般跑在localhost:3000,和你的PHP接口域名www.MYURL.com不是同一个源,所以浏览器会拦截跨域请求。cors-anywhere的作用是帮你转发请求,并给响应加上Access-Control-Allow-Origin头,绕过浏览器的CORS检查——但这只是开发临时手段,绝对不能用于生产环境。
部署后用代理为啥彻底失效?
因为部署后你的React app和PHP接口在同一个域名下(都是www.MYURL.com),这时候你再用cors-anywhere转发请求,反而会让请求变成从www.MYURL.com到cors-anywhere.herokuapp.com再回到你的接口,浏览器会认为这是跨域请求,而你的PHP接口还是没加CORS头,自然就报错了。而且cors-anywhere本身也会把请求重定向回你的接口,进一步触发CORS拦截。
最靠谱的解决方案:给PHP接口加CORS响应头
直接修改你的aov_API.php文件,在所有输出内容之前(必须是最顶部,连空格都不能有)添加以下代码:
<?php // 允许所有域名访问(如果要更安全,可以改成你的具体域名,比如http://www.MYURL.com) header("Access-Control-Allow-Origin: *"); // 允许常用的请求方法 header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许自定义请求头(如果你的请求需要带额外头的话) header("Access-Control-Allow-Headers: Content-Type"); // 处理浏览器的预检OPTIONS请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit(0); } // 你的原有PHP代码...
配置完之后,不管是本地开发还是部署后,都可以直接用相对路径请求接口,完全不需要代理。
修正你的React fetch代码
function App(){ async function updateQuote(type){ try { // 用相对路径,自动匹配当前域名 let newText = await fetch("/actionv/API/aov_API.php"); // 检查请求是否成功 if (!newText.ok) { throw new Error(`请求失败,状态码:${newText.status}`); } // 如果PHP返回的是JSON格式,用json()更方便,不用自己解析 // let msg = await newText.json(); // 如果是纯文本,用text() let msg = await newText.text(); console.log(msg); // 这里注意:如果msg已经是JSON字符串,你应该用JSON.parse,而不是JSON.stringify setQuoteText(msg); } catch (error) { console.error('获取名言出错了:', error); } } // 其他组件代码... }
本地开发的临时替代方案(如果暂时改不了PHP)
如果暂时没法修改PHP接口,本地开发时可以在React的package.json里添加代理配置:
"proxy": "http://www.MYURL.com"
这样本地开发时,所有未知路径的请求都会被自动代理到你的PHP服务器,同样可以用相对路径请求接口,不用依赖cors-anywhere。
重要提醒
永远不要依赖cors-anywhere这种第三方代理服务用于生产环境,不仅不稳定,还可能带来安全风险。正确的做法一定是后端配置CORS响应头,毕竟你的React和PHP在同一服务器上,配置起来非常简单。
内容的提问来源于stack exchange,提问作者Ben

