问题描述
我遇到的错误似乎是CORS问题。
The error I am getting seems to be a CORS issue.
我正尝试通过 HttpClient向RESTful API发出POST请求
如下:
import {Component, OnInit} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {HttpClient, HttpParams, HttpHeaders} from "@angular/common/http";
import { Test } from './test';
import { TestResponse } from './test.response';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import * as _ from 'lodash';
@Component({
selector: 'my-tests',
templateUrl: './tests.component.html',
styleUrls: ['./tests.component.css']
})
export class TestsComponent implements OnInit {
// URL to web api
private url = 'http://172.19.0.5/api/tests';
tests$: Observable<Test[]>;
private httpheadersPost = new HttpHeaders().set("Content-Type", "application/json");
constructor(private http:HttpClient) {
}
ngOnInit() {
// console.log(this.httpheadersPost);
this.tests$ = this.http
.get<TestResponse[]>(this.url)
.do(console.log)
.map(data => _.values(data["hydra:member"]));
}
// Implementation of the add() function
add(name: string): void {
// console.log('header:'+this.httpheadersPost);
// console.log(this.httpheadersPost);
name = name.trim();
if (!name) { return; }
this.http.post(this.url, {"name":name}, {"headers":this.httpheadersPost} )
.subscribe(
val => {
console.log("POST call successful value returned in body", val);
},
response => {
console.log("POST call in error", response);
},
() => {
console.log("The POST observable is now completed.");
}
);
}
}
我的RESTful API的nginx服务器的配置:
This is the config of my nginx server of my RESTful API:
server {
server_name symfony.dev;
root /var/www/symfony/public;
location / {
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
try_files $uri /index.php$is_args$args;
}
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|eof|woff|ttf)$ {
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
if (-f $request_filename) {
expires 30d;
access_log off;
}
}
location ~ \.php$ {
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_log /var/log/nginx/symfony_error.log;
access_log /var/log/nginx/symfony_access.log;
}
RESTful API和angular应用程序是通过创建的docker-compose
,因此容器的IP地址不同。
The RESTful API and the angular application are created through docker-compose
so containers are not having the same IP addresses.
我得到的错误是:
XMLHttpRequest无法加载。对预检请求的响应未通过访问控制检查:所请求的
资源中没有
Access-Control-Allow-Origin标头。因此,不允许
访问原始地址‘。响应的HTTP状态代码为405。
XMLHttpRequest cannot load http://172.19.0.5/api/tests. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4203' is therefore not allowed access. The response had HTTP status code 405.
IMO中的错误很奇怪。实际上,我已经提供了RESTful API的标头
+ nginx服务器具有 Access-Control-Allow-Origin
The error in IMO is strange. In fact, I already provided the headers
+ nginx server of the RESTful API is having Access-Control-Allow-Origin
which is already set.
感谢您的帮助。
推荐答案
问题在于,CORS无法以这种方式工作。当浏览器要在API上测试CORS时,它将向其发送OPTIONS请求。该请求应使用CORS标头和http代码 204
进行响应。
Well the problem is that CORS doesn't work this way. When browser wants to test CORS on an API it will send a OPTIONS request to it. This request should respond with the CORS header and a http code 204
.
所以您需要更新nginx配置如下所示。这不是确切的方法,但应该可以帮助您
So you would need to update you nginx config something like below. It is not exact, but should get you going
server {
server_name symfony.dev;
root /var/www/symfony/public;
location / {
# Match host using a hostname if you like
#if ($http_origin ~* (https?://.*\.tarunlalwani\.com(:[0-9]+)?$)) {
# set $cors "1";
#}
set $cors "1";
# OPTIONS indicates a CORS pre-flight request
if ($request_method = 'OPTIONS') {
set $cors "${cors}o";
}
# OPTIONS (pre-flight) request from allowed
# CORS domain. return response directly
if ($cors = "1o") {
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept' always;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
try_files $uri /index.php$is_args$args;
}
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|eof|woff|ttf)$ {
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
if (-f $request_filename) {
expires 30d;
access_log off;
}
}
location ~ \.php$ {
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Lang';
#add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_log /var/log/nginx/symfony_error.log;
access_log /var/log/nginx/symfony_access.log;
}
我最近使用了类似的配置为grafana启用CORS()。所以这也应该对你有用
I recently used a similar config to enable CORS for grafana (No response from Grafana via AJAX). So this should work for you also
这篇关于来自nginx API端点的响应的“无访问控制允许原点”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!