当我从 LAN 上的另一台 PC 浏览时,我的 ReactJS/Django(Rest API) 提示 Unhandled Promise 拒绝
Posted
技术标签:
【中文标题】当我从 LAN 上的另一台 PC 浏览时,我的 ReactJS/Django(Rest API) 提示 Unhandled Promise 拒绝【英文标题】:My ReactJS/Django(Rest API) prompts an Unhandled Promise rejection when I browse from a different PC on the LAN 【发布时间】:2021-07-25 13:31:40 【问题描述】:虽然我可以看到前端表单,但如果我尝试提交控制台会显示:“Fetch API 无法加载 http://localhost:8000/api/task-create/ 由于访问控制检查。” 下一行是:“加载资源失败:无法与服务器建立连接。”
这是我在我的电脑上看到的,(这没问题,每个功能都能完美运行)
这就是我在连接到同一个 LAN 的另一台 PC 上得到的
我认为它与标头和CORS,Django REST框架身份验证有关,我都尝试过但似乎不起作用。
有什么提示吗?
这是我的 settings.py:
Django settings for todoapp project.
Generated by 'django-admin startproject' using Django 3.2.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-whh5g$8**@u4t1m%13=c$6!k-5#o0jwhr&&7i7^d$ky%$ku+ls'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'api.apps.ApiConfig'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
ROOT_URLCONF = 'todoapp.urls'
TEMPLATES = [
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'frontend/build')
],
'APP_DIRS': True,
'OPTIONS':
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
,
,
]
WSGI_APPLICATION = 'todoapp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES =
'default':
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
,
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
,
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
,
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
,
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, javascript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend/build/static')
]
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ALLOWED_ORIGINS = [
"http://192.168.0.6:3000",
]
我的意见.py:
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .serializers import TaskSerializer
from .models import Task
# Create your views here.
@api_view(['GET'])
def apiOverview(request):
api_urls =
'List':'task-list/',
'Detail View':'/task-detail/<str:pk>',
'Create':'/task-create/',
'Update':'task-update/<str:pk>',
'Delete':'task-delete/<str:pk>',
return Response(api_urls)
@api_view(['GET'])
def taskList(request):
tasks = Task.objects.all()
serializer = TaskSerializer(tasks, many=True)
return Response(serializer.data)
@api_view(['GET'])
def taskDetail(request, id):
task = Task.objects.get(id=id)
serializer = TaskSerializer(task, many=False)
return Response(serializer.data)
@api_view(['POST'])
def taskCreate(request):
serializer = TaskSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['POST'])
def taskUpdate(request, id):
task = Task.objects.get(id=id)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def taskDelete(request, id):
task = Task.objects.get(id=id)
task.delete()
return Response('Task succesfully deleted!')
和我的 react 主组件 App.js:
import React from "react"
import './App.css';
import TodoItem from "./TodoItem"
import Form from "./Form"
class App extends React.Component
constructor(props)
super(props)
this.state =
todoList:[],
activeItem:
id:null,
title:'',
completed:false,
,
editing:false,
this.fetchTasks = this.fetchTasks.bind(this)
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.getCookie = this.getCookie.bind(this)
this.handleEdit = this.handleEdit.bind(this)
this.handleDelete = this.handleDelete.bind(this)
this.handleCompleted = this.handleCompleted.bind(this)
getCookie(name)
let cookieValue = null;
if (document.cookie && document.cookie !== '')
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++)
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '='))
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
return cookieValue;
componentDidMount()
this.fetchTasks()
fetchTasks()
fetch('http://localhost:8000/api/task-list/')
.then(response => response.json())
.then(data =>
this.setState(
todoList: data
)
)
handleChange(event)
let value = event.target.value
this.setState(
activeItem:
...this.state.activeItem,
title: value
)
handleSubmit(event)
event.preventDefault()
let csrftoken = this.getCookie('csrftoken')
let url='http://localhost:8000/api/task-create/'
if(this.state.editing === true)
url=`http://localhost:8000/api/task-update/$this.state.activeItem.id/`
this.setState(
editing: false
)
fetch(url,
method: 'POST',
headers:
'Content-type':'application/json',
'X-CSRFToken': csrftoken,
,
body: JSON.stringify(this.state.activeItem)
).then(()=>
this.fetchTasks()
this.setState(
activeItem:
id:null,
title:'',
completed:false,
)
).catch((e)=>
console.log('ERROR:',e)
)
handleEdit(todo)
this.setState(
activeItem: todo,
editing: true,
)
handleDelete(todo)
let csrftoken = this.getCookie('csrftoken')
let url = `http://localhost:8000/api/task-delete/$todo.id/`
fetch(url,
method: 'DELETE',
headers:
'Content-type': 'application/json',
'X-CSRFToken': csrftoken
).then((response)=>
this.fetchTasks()
).catch((error)=>
console.log('ERROR:',error)
)
handleCompleted(todo)
let csrftoken = this.getCookie('csrftoken')
const url=`http://localhost:8000/api/task-update/$todo.id/`
todo.completed= !todo.completed
fetch(url,
method:'POST',
headers:
'Content-type': 'application/json',
'X-CSRFToken': csrftoken
,
body: JSON.stringify(
title:todo.title,
completed:todo.completed,)
).then(()=>
this.fetchTasks()
).catch((e)=>
console.log('ERROR:',e)
)
render()
let todoItems = this.state.todoList.map((todo, id)=>
return(
<TodoItem
key=id todo=todo
onClick=()=> this.handleEdit(todo)
onDelete=()=> this.handleDelete(todo)
onCompleted=()=> this.handleCompleted(todo)
/>
)
)
return(
<div className="container">
<div id="task-container">
<Form
onChange=this.handleChange
onSubmit=this.handleSubmit
data=this.state.activeItem
/>
<div id="list-wrapper">
todoItems
</div>
</div>
</div>
)
export default App;
感谢您的帮助...
【问题讨论】:
【参考方案1】:您的 IP 地址可能有问题。比如,这台不同的计算机可能有一个激活的 *** 或任何其他指向其他 IP 地址而不是 localhost 的问题。
所以,在你的 django settings.py
中尝试改变这个:
CORS_ALLOWED_ORIGINS = [
"http://192.168.0.6:3000",
]
对这种方法:
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000',
]
或者如果你想允许所有:
CORS_ORIGIN_ALLOW_ALL = True # If you use this approach then `CORS_ORIGIN_WHITELIST` will not have any effect
CORS_ALLOW_CREDENTIALS = True
并检查它是否有效。
【讨论】:
以上是关于当我从 LAN 上的另一台 PC 浏览时,我的 ReactJS/Django(Rest API) 提示 Unhandled Promise 拒绝的主要内容,如果未能解决你的问题,请参考以下文章
在另一台 PC 上出现错误消息“禁止您无权访问 / 在此服务器上”
您无权访问此服务器上的 /phpmyadmin/。在 Windows 7 中访问另一个 pc localhost