解决Django API与React Native前端通信的CORS及网络连接问题
我用Django搭建后端应用,React Native开发前端,通过Android Studio的安卓模拟器运行RN应用。能正常访问外部接口,但访问本地Django接口(http://127.0.0.1:8000/api/movies/)时先遭遇CORS策略拦截,安装django-cors-headers并配置后,又出现「Network request failed」错误。以下是相关代码与环境信息,求解决通信连接的方法:
RN组件代码
import { ActivityIndicator, FlatList, Text, View } from "react-native"; import React, { Component } from "react"; export default class App extends Component { constructor(props) { super(props); this.state = { data: [], isLoading: true, }; } async getMovies() { try { const response = await fetch("http://127.0.0.1:8000/api/movies/", { method: "GET", headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", }, }); const json = await response.json(); this.setState({ data: json.movies }); } catch (error) { console.log(error); } finally { this.setState({ isLoading: false }); } } componentDidMount() { this.getMovies(); } render() { const { data, isLoading } = this.state; return ( <View style={{ flex: 1, padding: 24 }}> {isLoading ? ( <ActivityIndicator /> ) : ( <FlatList data={data} keyExtractor={({ id }, index) => id} renderItem={({ item }) => <Text>{item.title}</Text>} /> )} </View> ); } }
Postman返回的Django接口数据
[ { "id": 1, "title": "Husband", "description": "Very nice wife cocks the man", "no_of_ratings": 1, "avg_rating": 5.0 }, { "id": 2, "title": "Nice movie", "description": "Description ah, niceNICE", "no_of_ratings": 0, "avg_rating": 0 } ]
初始错误信息
Access to fetch at 'http://127.0.0.1:8000/api/movies/' from origin 'http://localhost:19006' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
安装django-cors-headers后的Django配置
CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", ]
修改后的RN请求代码
useEffect(() => { fetch("http://127.0.0.1:8000/animalGroups/group/", { method: "GET", }) .then((res) => res.json()) .then((jsonres) => setAnimalGroup(jsonres)) .catch((error) => console.error(error)); }, []);
RN应用运行地址
› Opening exp://192.168.1.69:19000 on MY_ANDROID
当前错误信息
Network request failed
at node_modules\whatwg-fetch\dist\fetch.umd.js:null in setTimeout$argument_0
解决步骤
1. 修正Android模拟器访问本地后端的地址
Android模拟器中的127.0.0.1指向模拟器自身,而非你的电脑。需替换为电脑的局域网IP(即RN运行地址中的192.168.1.69),或使用模拟器专属映射地址10.0.2.2(对应电脑的127.0.0.1)。
示例请求地址修改为:
"http://192.168.1.69:8000/api/movies/"
或
"http://10.0.2.2:8000/api/movies/"
2. 完善Django的CORS配置
- 确保
django-cors-headers正确加入项目配置:INSTALLED_APPS = [ # 其他已安装应用 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 必须放在CommonMiddleware之前 'django.middleware.common.CommonMiddleware', # 其他中间件 ] - 更新
CORS_ALLOWED_ORIGINS,包含RN的实际来源:CORS_ALLOWED_ORIGINS = [ "http://localhost:19006", "http://192.168.1.69:19000", "http://10.0.2.2:19000", ] # 开发阶段可临时允许所有来源(生产环境禁用) # CORS_ALLOW_ALL_ORIGINS = True
3. 确保Django服务绑定到所有网卡
启动Django时,让服务监听所有网卡,保证模拟器能访问:
python manage.py runserver 0.0.0.0:8000
4. 移除RN请求中多余的响应头
Access-Control-Allow-Origin是后端返回给前端的响应头,前端请求中添加无效,直接删除:
# 删掉请求headers中的这一行 "Access-Control-Allow-Origin": "*",
内容的提问来源于stack exchange,提问作者mightycode Newton

