' Access-Control-Allow-Origin'标头包含多个值' http:// localhost:4200,*'

时间:2018-03-21 08:33:24

标签: angular docker cors

我正在使用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容器中运行,其定义如下:

搬运工-撰写-backend.yml

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

后端的nginx服务器的配置

请注意,如果前端在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并不是很方便。

谢谢,

0 个答案:

没有答案