ReactJS与PHP交互遇跨域报错:Access-Control-Allow-Origin缺失求助
解决React + PHP(WordPress)交互的CORS问题及代码修正
看起来你遇到了浏览器同源策略导致的CORS错误,同时代码里还有一些小细节需要调整,我来一步步帮你搞定:
一、CORS错误的核心解决方法
浏览器阻止跨源请求,是因为你的React开发服务器(通常是http://localhost:3000)和WordPress服务器(http://domain.com)属于不同的源。下面两种方法都能解决这个问题:
方法1:在PHP接口中添加CORS响应头
这是最直接的方式,一定要把响应头放在任何输出之前(包括引入WordPress文件之前),避免header发送失败:
<?php // 开发环境可以用*允许所有源,生产环境请替换成你的React部署地址 header("Access-Control-Allow-Origin: http://localhost:3000"); // 只允许GET请求(你的接口逻辑是GET) header("Access-Control-Allow-Methods: GET"); header("Access-Control-Allow-Headers: Content-Type"); // 明确返回JSON格式 header("Content-Type: application/json"); require($_SERVER['DOCUMENT_ROOT'] . '/wp-blog-header.php'); global $post; $args = array( 'numberposts' => '10', 'offset' => '27', 'post_type' => 'product', 'post_status' => 'publish', 'orderby' => 'menu_order', 'order' => 'ASC' ); $products = get_posts($args); // 你原来的foreach是多余的,直接赋值即可 $result = $products; echo json_encode($result);
方法2:使用React开发服务器代理(推荐开发环境)
不需要修改PHP,在React项目的package.json中添加proxy字段,指向你的WordPress域名:
{ "name": "your-react-app", "version": "0.1.0", "proxy": "http://domain.com", // 替换成你的WordPress域名 // ...其他字段 }
然后修改axios请求,不用写完整URL,直接用相对路径:
axios.get('/db.php') .then(({ data }) => { this.setState({ result: data }); }) .catch(err => console.error('请求失败:', err));
这样React开发服务器会自动把请求代理到WordPress服务器,避开CORS限制。
二、React代码的细节修正
你的index.js里有几个小问题,即使CORS解决了,页面也无法正常渲染,需要调整:
1. 正确定义App组件并初始化state
你需要把componentWillMount和render放在组件类中,并且初始化state避免报错:
import React from 'react'; import ReactDOM from 'react-dom'; import registerServiceWorker from './registerServiceWorker'; import axios from "axios"; import Product from "./Product"; class App extends React.Component { constructor(props) { super(props); // 初始化state,防止map时出现undefined错误 this.state = { result: [] }; } // 推荐用componentDidMount代替componentWillMount(React官方已标记后者为不安全) componentDidMount() { // 用方法1的话写完整URL,用方法2的代理写'/db.php'即可 axios.get('http://domain.com/db.php') .then(({ data }) => { this.setState({ result: data }); }) .catch(err => console.error('请求出错:', err)); } render() { return( <div className="products"> {this.state.result.map((product, i) => ( // 注意props名称要和Product组件的参数一致 <Product key={i} post_title={product.post_title} guid={product.guid} /> ))} </div> ); } } ReactDOM.render(<App />, document.getElementById('root')); registerServiceWorker();
2. 修正Product组件的props匹配
你的Product组件接收的是post_title和guid参数,调用时要保持名称一致(原来的代码传的是title,会导致值undefined):
// Product.js 保持不变即可 import React from 'react'; const Product = ({post_title, guid}) => ( <div> <div>{post_title}</div> <div>{guid}</div> </div> ); export default Product;
当然你也可以把Product组件的参数改成title,然后调用时传title={product.post_title},只要匹配就行。
三、额外提示
- 生产环境中,如果React和PHP部署在同一域名下,CORS问题会自动消失,不需要额外配置;
- 生产环境别用
Access-Control-Allow-Origin: *,请指定具体的域名,比如http://your-react-domain.com; - 建议在请求中添加错误捕获,方便排查问题。
内容的提问来源于stack exchange,提问作者147armedru
相关产品推荐
相关产品推荐

