[英]How to connect Expo GO App to Django Rest Framework Backend on localhost?
I am implementing a react native application using Expo and testing it on my iOS device using Expo Go. I have a Django rest framework backend running on my local machine that I can access using my browser via http://localhost:8000 - using localhost in my react native app does not work during my fetch request.我正在使用Expo实施反应应用程序,并在我的iOS使用886262693677288 886027161488进行测试。在我的获取请求期间,我的本机应用程序无法正常工作。 For instance:
例如:
let response = await fetch(BACKEND_URL + "/shft/auth/token/obtain/", {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
});
returns回报
Network request failed
at node_modules\whatwg-fetch\dist\fetch.umd.js:null in setTimeout$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _allocateCallback$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in callTimers
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __callFunction
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in callFunctionReturnFlushedQueue
I have tried setting BACKEND_URL to localhost:8000 and my public IP via expo-constants我尝试通过 expo-constants 将BACKEND_URL 设置为 localhost:8000和我的 public IP
import Constants from "expo-constants";
const { manifest } = Constants;
const uri = `http://${manifest.debuggerHost.split(":").shift()}:8000`;
But neither seems to work.但似乎都不起作用。 I have enabled the Corsheaders middleware in my DRF project and placed the @csrf_exempt decorator on my APIView's dispatch method, and this error persists.
我在我的 DRF 项目中启用了 Corsheaders 中间件,并将 @csrf_exempt 装饰器放在我的 APIView 的调度方法上,但此错误仍然存在。 I also added localhost:19000 to my CORS whitelist, which is where Expo seems to host its local server.
我还将 localhost:19000 添加到我的 CORS 白名单中,这是 Expo 似乎托管其本地服务器的地方。 What could be the problem here?
这里可能是什么问题? Both the Expo server and the Django server are running locally on my laptop, and otherwise the API works in Django tests.
Expo 服务器和 Django 服务器都在我的笔记本电脑上本地运行,否则 API 在 Django 测试中工作。
Using curl on my API endpoints via localhost also works, though the external IP returned by expo constants does not—but this may be because I am sending from localhost.通过本地主机在我的 API 端点上使用 curl 也可以,尽管由 expo 常量返回的外部 IP 不起作用——但这可能是因为我是从本地主机发送的。
I found a fix using information from these two posts: this stack overflow and this blog .我使用这两个帖子中的信息找到了一个修复程序:这个stack overflow和这个blog 。 Neither of these solutions worked for me out of the box but a little.networking logic makes it all come together.
这些解决方案都不是开箱即用的,但有点。网络逻辑使它们结合在一起。 The core issue here is that the Django server is hosted locally but the Expo Go App is running on a separate mobile device (despite the expo server being hosted locally as well).
这里的核心问题是 Django 服务器在本地托管,但 Expo Go 应用程序在单独的移动设备上运行(尽管 expo 服务器也在本地托管)。 I've tested each of the following steps to make sure they are all necessary.
我已经测试了以下每个步骤以确保它们都是必要的。
pip install django-cors-headers
then add it to your INSTALLED_APPS and Middleware in settings.py
pip install django-cors-headers
然后将其添加到settings.py
中的 INSTALLED_APPS 和中间件INSTALLED_APPS = [
...,
'corsheaders',
]
# make sure CorsMiddleware comes before CommonMiddleware
MIDDLEWARE = [
...,
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...,
]
Also use the @csrf_exempt decorator on the views you must be able to access (there are security implications to this but I am using JWT authentication anyways for this mobile app so this is okay in my case - I would do my due diligence here).还要在您必须能够访问的视图上使用 @csrf_exempt 装饰器(这有安全隐患,但无论如何我都为此移动应用程序使用 JWT 身份验证,所以这对我来说没问题 - 我会在这里尽职调查)。 There are a few ways to do this for function and class views:
对于 function 和 class 视图,有几种方法可以做到这一点:
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view():
...
# or for class based views
class my_view(APIView):
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
return super().dispatch(self, request, *args, **kwargs)
# or my preferred way for easy copy paste
@method_decorator(csrf_exempt, name='dispatch')
class my_view(APIView):
...
# specify this IP to expose on LAN
python manage.py runserver 0.0.0.0:8000
Find your local machine's IP address - the blog above uses the mobile device's IP but that did not work for me, which makes sense given that both servers are running on my laptop.找到您本地计算机的 IP 地址 - 上面的博客使用移动设备的 IP 但这对我不起作用,考虑到两台服务器都在我的笔记本电脑上运行,这是有道理的。 For windows I opened the command prompt and entered
ipconfig
then found the IPv4......
line which contains my address.对于 windows,我打开命令提示符并输入
ipconfig
,然后找到IPv4......
包含我的地址的行。
Use this IP to direct your API calls and add it to your CORS whitelist.使用此 IP 来引导您的 API 呼叫并将其添加到您的 CORS 白名单中。 For example if your localmachine IP is 10.0.0.1 and Expo is on port 19000 while Django is on port 8000 we add the following.
例如,如果您的本地计算机 IP 是 10.0.0.1 并且 Expo 在端口 19000 上,而 Django 在端口 8000 上,我们添加以下内容。
# Django settings.py
ALLOWED_HOSTS = ['10.0.0.1',]
CORS_ORIGIN_WHITELIST = [
'http://10.0.0.1:19000',
]
// Wherever you define the backend URL for the frontend, in my case config.js
export const BACKEND_URL = "http://10.0.0.1:8000"
// Then make requests
fetch(BACKEND_URL + "/api/endpoint/", ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.