我正在开发一个使用角+ Django(Django Rest Framework)的项目。在开发过程中,CORS支持是使用django-cors-标头、CORS_ORIGIN_ALLOW_ALL = True和CORS_ALLOW_CREDENTIALS = True完成的。
当我试图发送POST请求以在前端创建一些资源(角)时,一些飞行前选项请求由Chrome发送,并由后端服务器(python )成功地响应,而另一些则没有。这些请求由于未知的原因而被取消,后端服务器日志表示服务器接收和接受请求,详情如下图所示。


失败请求的标题如下所示。

但是,如果复制标头的内容并尝试将其与curl一起发送,则它将按预期的方式工作。
$ curl -v -X OPTIONS -H "Access-Control-Request-Headers: authorization,content-type" -H "Access-Control-Request-Method: POST" -H "DNS: 1" -H "Origin: http://localhost:4200" -H "Referer: http://localhost:4200" -H "User-Agent: Mozilla/5.0" http:/localhost:8000/api/user-permissions/
* Unwillingly accepted illegal URL using 1 slash!
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 8000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> OPTIONS /api/user-permissions/ HTTP/1.1
> Host: localhost:8000
> Accept: */*
> Access-Control-Request-Headers: authorization,content-type
> Access-Control-Request-Method: POST
> DNS: 1
> Origin: http://localhost:4200
> Referer: http://localhost:4200
> User-Agent: Mozilla/5.0
>
< HTTP/1.1 200 OK
< Date: Wed, 20 Feb 2019 02:47:39 GMT
< Server: WSGIServer/0.2 CPython/3.7.1
< Content-Type: text/html; charset=utf-8
< Content-Length: 0
< Vary: Origin
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: http://localhost:4200
< Access-Control-Allow-Headers: accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with
< Access-Control-Allow-Methods: DELETE, GET, OPTIONS, PATCH, POST, PUT
< Access-Control-Max-Age: 86400
<
* Connection #0 to host localhost left intact知道这是怎么发生的吗?谢谢。
样本代码:
// The method of the component that invokes the methods of PermissionService.
/** Update selected user's permissions. */
updatePermissions() {
const diff = this.diffPermissions();
const toBeCreated = diff[0];
const toBeDeleted = diff[1];
this.isLoading = true;
zip(
this.permissionService.createUserPermissions(toBeCreated),
this.permissionService.deleteUserPermissions(toBeDeleted),
).pipe(
map(() => true),
catchError((err: HttpErrorResponse) => {
alert(err.message);
return observableOf(false);
}),
).subscribe(succeed => {
this.isLoading = false;
});
}
// The methods of PermissionService that issue the HTTP requests.
createUserPermission(req: UserPermissionRequest) {
return this.http.post(`${environment.API_URL}/user-permissions/`, req);
}
createUserPermissions(reqs: UserPermissionRequest[]) {
// TODO(youchen): Evaluate the performance cost.
return forkJoin(reqs.map(req => this.createUserPermission(req)));
}
deleteUserPermission(permissionId: number) {
return this.http.delete(`${environment.API_URL}/user-permissions/${permissionId}/`);
}
deleteUserPermissions(permissionIds: number[]) {
// TODO(youchen): Evaluate the performance cost.
return forkJoin(permissionIds.map(id => this.deleteUserPermission(id)));
}发布于 2019-02-21 02:09:54
找到原因:没有参数的zip()
在我的例子中,我使用zip组合创建和删除,请参见:
const createRequests = [c1, c2];
const deleteRequests = [d1, d2];
zip(
this.service.create(createRequests),
this.service.delete(deleteRequests),
)....
---
service.ts
create(reqs: CreateRequest[]) {
return zip(...reqs.map(req => this.createSingle(req));
}
delete(reqs: DeleteRequest[]) {
return zip(...reqs.map(req => this.deleteSingle(req));
}但是,如果其中一个createRequests和deleteRequests是空列表,那么这个逻辑就会出错。例如,如果createRequests是空的,而deleteRequests不是空的,那么由this.service.delete(deleteRequests)触发的所有HTTP请求都将被取消,因为this.service.create(createRequests)会返回空的zip()。
解决方案:
这个问题的解决方案是,我们检查reqs的长度,并返回其他可观察的实例化。
固定代码:
create(reqs: CreateRequest[]) {
if (reqs.length === 0) return of([]);
return zip(...reqs.map(req => this.createSingle(req));
}
delete(reqs: DeleteRequest[]) {
if (reqs.length === 0) return of([]);
return zip(...reqs.map(req => this.deleteSingle(req));
}https://stackoverflow.com/questions/54778120
复制相似问题