React Native+Redux调用Laravel API出现网络请求失败问题
解决React Native调用Laravel API的Network request failed问题
针对你遇到的React Native结合Redux调用Laravel API时出现的网络请求失败错误,以下是具体的排查和解决步骤:
1. 修正Laravel服务的监听地址
默认php artisan serve仅监听本地127.0.0.1,导致手机或模拟器无法访问。需启动服务时指定监听所有网卡:
php artisan serve --host=0.0.0.0 --port=8000
之后使用电脑的局域网IP(如http://192.168.1.30:8000/api/jobs)作为API地址。
2. 配置React Native的网络安全策略
Android端
在android/app/src/main/AndroidManifest.xml的<application>标签中添加:
android:usesCleartextTraffic="true"
(Android 9及以上默认禁止明文HTTP请求,此配置允许本地HTTP访问)
iOS端
在ios/[你的项目名]/Info.plist中添加以下配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
或更严谨地针对特定IP配置例外(推荐):
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>192.168.1.30</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
3. 确保设备与电脑在同一局域网
- 手机需和运行Laravel的电脑连接同一个WiFi网络;
- Android模拟器可使用
http://10.0.2.2:8000/api/jobs访问电脑本地服务(模拟器的10.0.2.2对应电脑的127.0.0.1); - iOS模拟器可直接使用
127.0.0.1或局域网IP。
4. 修复Redux Action的错误处理逻辑
当前代码的try/catch未捕获fetch的异步错误,需将错误处理移至dispatch的异步函数内部:
export const GET_JOB_POSTS = "GET_JOB_POSTS"; const apiURL = "http://192.168.1.30:8000/api/jobs"; export const getJobs = () => { return async dispatch => { try { const result = await fetch(apiURL, { method: "GET", headers: { "Content-Type": "application/json", } }); // 检查HTTP状态码,处理非200的情况 if (!result.ok) { throw new Error(`HTTP error! status: ${result.status}`); } const json = await result.json(); dispatch({ type: GET_JOB_POSTS, payload: json }); } catch(error) { console.error("Fetch error:", error); // 可在此处添加错误状态的dispatch } } }
5. 配置Laravel的CORS权限
安装并配置Laravel CORS中间件,确保允许React Native的请求:
- 安装依赖:
composer require barryvdh/laravel-cors
- 在
app/Http/Kernel.php的$middleware数组中添加:
\Barryvdh\Cors\HandleCors::class,
- 发布配置文件并修改
config/cors.php,设置允许的来源、方法等:
return [ 'paths' => ['api/*'], 'allowed_methods' => ['*'], 'allowed_origins' => ['*'], // 开发环境可设为*,生产环境指定具体域名 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => false, ];
内容的提问来源于stack exchange,提问作者Peter Yan
相关产品推荐
相关产品推荐

