VMF*_*VMF 2 python cors django-rest-framework angular
我在使用 Angular 6 应用程序中的 Django Rest Framework REST API 时遇到 CORS 问题。
该 API 在http://localhost:55098/admin上运行。当我用 Insomnia 调用它时它工作得很好。Angular 应用程序在http://localhost:4200上运行。
当我第一次输入http://localhost:4200/cgestores时,它应该重定向到http://localhost:55098/admin/cgestores,并且确实如此,但我收到了 CORS 错误消息(见下文)。
我的配置:
REST API:我使用Python 3.7(64位),Django(2.1.5)和Django Rest Framework(3.9.1)
我的设置.py:
ALLOWED_HOSTS = [
'testserver',
'localhost'
]
CORS_ORIGIN_ALLOW_ALL = True
INSTALLED_APPS = [
# Add your apps here to enable them
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_swagger',
'corsheaders',
'admin_v20',
]
MIDDLEWARE_CLASSES = [
'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.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Run Code Online (Sandbox Code Playgroud)
Angular 客户端:我正在使用 Angular 6.4.1。服务(apiusuarios.service.ts):
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse, HttpParams } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ApiusuariosService {
datos: iCentroGestor;
constructor(private http: HttpClient) { }
getMock(): any{
return [
{"gececo":"a", "gecdes":"one"},
{"gececo":"b", "gecdes":"two"},
{"gececo":"c", "gecdes":"three"}
];
}
getUsers(): Observable<any> {
return this.http.get(endpoint + 'cgestores').pipe(map(this.extractData));
}
}
export interface iCentroGestor {
gececo: string;
gecdes: string;
}
const endpoint = 'http://localhost:55098/admin/';
Run Code Online (Sandbox Code Playgroud)
方法getMock()
返回一个固定的 JSON 值仅用于测试目的,并且工作正常。真正调用API的方法是getUsers()
, 是触发CORS错误的方法:
从源“ http://localhost: 4200 ”访问位于“http://localhost:55098/admin/cgestores/”的XMLHttpRequest已被 CORS 策略阻止:不存在“Access-Control-Allow-Origin”标头所请求的资源。
(即 Chrome;Firefox 和 Edge 返回类似的响应)
这似乎是很多人的问题,我检查了这些文章:
...还有更多,还有这个视频:
...他们几乎都说了同样的话:这不是 Angular 问题,而是服务器问题,我应该对我的 DRF 项目进行以下修改:
安装 CORS 标头包
使用以下内容修改 settings.py:
一切都完成了,但还是没有成功。在尝试了所有这些之后,我了解到我可以在响应中指定我需要的标头。所以我在我的 DRF 项目中尝试了这个:
return Response(data=pDatos, status=pStatus, headers={"Access-Control-Allow-Origin":"*"})
Run Code Online (Sandbox Code Playgroud)
...宾果游戏,它成功了!
然而,这并不是真正的解决方案,我不喜欢必须依赖于特定响应的特定参数。而且,最重要的是,我无法限制谁可以访问该网站,谁不能访问该网站,这使用 CORS_ORIGIN_WHITELIST 非常容易做到(好吧,我可以,但是编写一个包含网站列表的参数星号符号似乎不是正确的选择)。
那么,我做错了什么?为什么我的settings.py
选项不起作用?我把它们注释掉了,然后就离开了return Response...
,它仍然有效,所以并settings.py
没有真正做任何事情。
抱歉发这么长的帖子。有任何想法吗?在此先感谢您的帮助。
小智 5
首先使用 pip 安装 django-cors-headers
pip install django-cors-headers
Run Code Online (Sandbox Code Playgroud)
您需要将其添加到项目的 settings.py 文件中:
INSTALLED_APPS = (
##...
'corsheaders'
)
Run Code Online (Sandbox Code Playgroud)
接下来需要将 corsheaders.middleware.CorsMiddleware 中间件添加到 settings.py 中的中间件类中
MIDDLEWARE = (
'corsheaders.middleware.CorsMiddleware',
#...
)
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过添加以下设置为所有域启用 CORS
CORS_ORIGIN_ALLOW_ALL = True
Run Code Online (Sandbox Code Playgroud)
或者仅对指定域启用 CORS:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http://localhost:8000', # Allowed host, if CORS_ORIGIN_ALLOW_ALL is False
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4594 次 |
最近记录: |