我正在使用angular5开发前端应用程序。在开发模式下,前端应用程序使用以下命令ng serve
启动,然后可以从此URL http://localhost:4200/访问该应用程序。
这让我有CORS访问错误:
无法加载http://172.19.0.3/api/countries:' Access-Control-Allow-Origin'标头包含多个值' http://localhost:4200,*',但只允许一个。起源' http://localhost:4200'因此不允许访问。
请注意,后端应用程序在docker容器中运行,其定义如下:
version: '2'
services:
backend:
build: backend-symfony
ports:
- 81:80
volumes:
- ./backend-symfony/backend/var/logs-nginx:/var/log/nginx
- ./backend-symfony/backend/:/var/www/html
- ./backend-symfony/errors/:/var/www/errors
db:
image: mysql:5.7.19
ports:
- 3306
volumes:
- "./.data/db:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
phpmyadmin:
image: phpmyadmin/phpmyadmin:edge-4.7
ports:
- 8080:80
links:
- db
请注意,如果前端在docker容器中运行,CORS的配置是完美的(但在开发模式下它不起作用)
server {
listen 80; ## listen for ipv4; this line is default and implied
listen [::]:80 default ipv6only=on; ## listen for ipv6
root /var/www/html/public;
index index.php;
# Make site accessible from http://localhost/
server_name _;
# Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html
sendfile off;
# Add stdout logging
error_log /dev/stdout info;
access_log /dev/stdout;
# Add option for x-forward-for (real ip when behind elb)
#real_ip_header X-Forwarded-For;
#set_real_ip_from 172.16.0.0/12;
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, PATCH' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Lang, Authorization' 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 unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# # pass the PHP scripts to FastCGI server listening on socket
# #
# location ~ \.php$ {
# # try_files $uri =404;
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# fastcgi_pass unix:/var/run/php-fpm.sock;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_param SCRIPT_NAME $fastcgi_script_name;
# fastcgi_index index.php;
# include fastcgi_params;
# }
#
# location ~* \.(jpg|jpeg|gif|png|css|js|ico|webp|tiff|ttf|svg)$ {
# expires 5d;
# }
# # deny access to . files, for security
# #
# location ~ /\. {
# log_not_found off;
# deny all;
# }
#
# location ^~ /.well-known {
# allow all;
# auth_basic off;
# }
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
// import { HttpClientModule } from '@angular/common/http';
// Grab everything with import 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import { Observer } from 'rxjs/Observer';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import * as _ from 'lodash';
import { ICountry } from '@app/shared/interfaces';
@Injectable()
export class DataService {
// baseUrl = 'http://backend/api';
baseUrl = 'http://172.19.0.3/api';
constructor(private http: HttpClient) { }
// private httpheadersGet = new HttpHeaders().set("Access-Control-Allow-Origin", "http://localhost:4200");
public getCountries(): Observable<ICountry[]> {
return (
this.http
.get<ICountry[]>(this.baseUrl + '/countries'/* , {"headers": this.httpheadersGet} */)
.do(console.log)
.map(data => _.values(data["hydra:member"]))
.catch(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
console.error('server error:', error);
if (error.error instanceof Error) {
const errMessage = error.error.message;
return Observable.throw(errMessage);
// Use the following instead if using lite-server
// return Observable.throw(err.text() || 'backend server error');
}
return Observable.throw(error || 'Node.js server error');
}
}
是否有任何解决方案可以避免开发模式下的CORS错误?在开发中制作ng build --prod
并不是很方便。
谢谢,