简体   繁体   English

如何将 Expo GO App 连接到本地主机上的 Django Rest 框架后端?

[英]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.我已经测试了以下每个步骤以确保它们都是必要的。

  1. Set up Django CORS using the corsheaders app and the corresponding middleware, there are guides on how to do this but basically pip install django-cors-headers then add it to your INSTALLED_APPS and Middleware in settings.py使用 corsheaders 应用程序和相应的中间件设置 Django CORS,有关于如何执行此操作的指南,但基本上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):
...

  1. Expose the Django server over LAN, this step is necessary so that your device can interface with the Django server over the local.network - may not be necessary if using an emulator (though I'm aware that the Android emulator for instance accesses localhost using a specially designated IP address so I would check for this).通过 LAN 公开 Django 服务器,此步骤是必要的,以便您的设备可以通过 local.network 与 Django 服务器交互 - 如果使用模拟器则可能不是必需的(尽管我知道 Android 模拟器例如访问 localhost 使用一个特别指定的 IP 地址,所以我会检查这个)。
# specify this IP to expose on LAN
python manage.py runserver 0.0.0.0:8000
  1. 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......包含我的地址的行。

  2. 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.

相关问题 如何在测试环境中将 Django rest 框架连接到 android 应用程序中? - How to connect a Django rest framework into android app in testing environment? Django REST框架过滤器后端 - Django REST Framework filter backend 如何使用django只有一个后端并使用django-rest-framework发布 - How to use django only a backend and post with django-rest-framework 在Django Rest Framework中,后端如何检查文件上传是否为多个? - In Django Rest Framework, how can the backend check if the files upload is multiple or not? Django REST 框架 - 如何在前端事件发生后在后端启动函数 - Django REST Framework - how to start functions on backend after event on frontend 使用Django REST Framework作为Django的身份验证后端 - Using Django REST Framework as an authentication backend for Django django过滤后端在django rest框架中的条件? - Conditions on django filter backend in django rest framework? 部署 Django、Django REST 框架后端和 VueJS + Z424516CA53B475A88 前端 onGCP 引擎(标准) - Deploying Django, Django REST Framework backend & VueJS + webpack frontend on GCP App Engine (standard) 电子商务的 Rest-framework 资源中的 Django 后端 - Django backend in Rest-framework resource for eCommerce Django Rest Framework过滤后端和过滤器类 - Django Rest Framework filter backend and filter class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM