docker react+django,从源'http://localhost'访问'http://localhost:8000'处的XMLHttpRequest已被CORS策略阻止

ttcibm8c  于 2023-04-05  发布在  Docker
关注(0)|答案(1)|浏览(225)

我有一个docker,在后端运行Django和DRF的服务,另一个在前端运行react,我试图从react向Django服务器发出API调用

const getRealItems = () => {
    axios.get(`http://localhost:8000/item`).then(
      (response) => {
        console.log("realItems = ", response)
      }
    )
  }

这个端点在浏览器上或通过失眠正常工作,并返回一个200的数据,我也试图将我的方法上的端点替换为口袋妖怪API,并收到一个200的数据,所以该方法是好的
问题是击中了我的服务器上的端点
这是我的settings.py

...

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    ...
    'rest_framework',
    'restaurant',
    'corsheaders',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost",
    "http://localhost:80",
]

CORS_ORIGIN_ALLOW_ALL = True

...

我把这个加到了我的viewset.py

class MenuItemViewSet(ModelViewSet):
    queryset = MenuItem.objects.all()
    serializer_class = MenuItemSerializer

    #GET
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

    def finalize_response(self, request, response, *args, **kwargs):
        response["Access-Control-Allow-Origin"] = "*"
        return super().finalize_response(request, response, *args, **kwargs)

这是我的docker-compose的情况下是必要的

version: "3.7"
services:

  database:
    build:
      context: .
      dockerfile: Dockerfile.postgres
    restart: always
    user: root
    volumes:
      - ./backup_data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

  backend:
    build: ./backend
    volumes:
      - ./backend:/app
    depends_on:
      - database
  
  frontend:
    build: ./frontend
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - backend
    ports:
      - 80:80

  do-migration:
    build: ./backend
    depends_on:
      - backend
    command:
      - /bin/bash
      - -c
      - |
        echo "Apply migration"
        python manage.py makemigrations
        python manage.py migrate
        exit 0
    volumes:
      - ./backend:/app
  
  nginx_backend_server:
    build: ./nginx_backend_server
    restart: always
    ports:
        - 8000:8000
    depends_on:
        - backend

但我犯了个错误

Access to XMLHttpRequest at 'http://localhost:8000/item' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

编辑1:
添加一些修改到我的settings.py,同样的错误

CORS_ALLOWED_ORIGINS = [
    "http://localhost",
    "http://localhost:8000",
]

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_METHODS = ("DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT")

CORS_ALLOW_HEADERS = (
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
    "x-user-agent",
)

可能是我的前端应用程序缺少了一些配置吗?

atmip9wb

atmip9wb1#

在这上面花了整整一个周末之后,我想出了解决方案,以防将来有人在这上面绊倒:
在INSTALLED_APPS上,corsheaders必须在您的应用程序上方

CORS_ORIGIN_WHITELIST = [
    'http://localhost',
    'http://localhost:3000',  # for localhost (REACT Default)
]

CORS_ALLOWED_ORIGINS = [
    'http://localhost',
    'http://localhost:3000',  # for localhost (REACT Default)
]

CORS_ALLOW_HEADERS = ["origin"]

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_ALL_ORIGINS = True

curl请求应该设置Referrer-policy

curl -I http://localhost:8000

HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Mon, 03 Apr 2023 02:22:15 GMT
Content-Type: application/json
Content-Length: 69
Connection: keep-alive
Vary: Accept, Cookie, Origin
Allow: GET, HEAD, OPTIONS
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin

最后,关于我的:axios.get(http://localhost:8000/item
被重定向到'http://localhost:8000/item/',所以我必须在请求后面附加/

相关问题