Angular和PHP项目"Access-Control-Allow-Origin"标头包含多个值 [英] Angular and PHP project 'Access-Control-Allow-Origin' header contains multiple values

查看:156
本文介绍了Angular和PHP项目"Access-Control-Allow-Origin"标头包含多个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发基于php和angular 6的单页应用程序.

I am working on a php and angular 6 based single page application.

除今天在控制台上看到以下错误外,项目正常运行:

The project runs normally except for today when I saw the following error at the console:

通过' http://dev.local/scripts/login.php '来自 来源' http://localhost:4200 已被CORS政策阻止: 'Access-Control-Allow-Origin'标头包含多个值 " http://localhost:4200 ,*",但只允许一个.

Access to XMLHttpRequest at 'http://dev.local/scripts/login.php' from origin 'http://localhost:4200' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4200, *', but only one is allowed.

通过dev.local我的意思是,使用wampserver创建的虚拟主机用于测试.

By dev.local I mean, the virtual host created using wampserver for testing purposes.

在login.php上,我具有以下脚本:

On login.php, I have the following scripts:

PHP 调用脚本:

<?php

require_once('../api.php');

//Getting username and password from Angular

$user = $_POST['username'];
$password = $_POST['password'];

$newApi = new api();
$conn = $newApi->connection();
//var_dump($conn);
$res = $newApi->login($conn, $user, $password);

echo json_encode($res);
?>

在API上:

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS');
header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
error_reporting(E_ALL);

require_once('JWT.php');

include_once('../phpmailer/PHPMailer.php');
include_once('../phpmailer/POP3.php');
include_once('../phpmailer/SMTP.php');
include_once('../phpmailer/Exception.php');
class api {
    private $username ="root";
    private $password ="root";
    private $db="reg_sys";
    private $host = "localhost";
    public $conn;
    public $key = "key123";
    public $sessionJwt;
    public function connection(){
        session_start();
        try{
            $this->conn = new PDO("mysql:host=$this->host;dbname=$this->db", $this->username, $this->password);
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->conn->exec("SET CHARACTER SET utf8");

            return $this->conn;
        }
        catch(PDOException $e){
            return $e->getMessage();
        }

    }
public function login($conn, $user, $password){

        try{
            $exist = $this->checkIfUserExist($conn, $user);
            if($exist['exist'])
            {
                //Check Password and Generate a token
                $checkPassword = "SELECT user_id, user_name, user.role_id, roles.role_type 
                FROM user
                    LEFT JOIN roles ON user.role_id = roles.role_id 
                WHERE 
                    user_name = :user 
                AND 
                    user_password = :pass
                LIMIT 1";

                $execCheckPassword = $this->conn->prepare($checkPassword);
                $execCheckPassword->bindValue('user', $user);
                $execCheckPassword->bindValue('pass', $password);
                $execCheckPassword->execute();
                $fetchRes = $execCheckPassword->fetch();
                $resFound = $execCheckPassword->rowCount();
                //Then
                if($resFound>0)
                {
                    //Generate a JWT
                    //Array to generate a JWT from

                    $arrayJWT = 
                    [
                        'login_id'=>$fetchRes['user_id'],
                        'username'=> $fetchRes['user_name'], 
                        'user_role'=>$fetchRes['role_type']
                    ];

                    $encodedJWT = JWT::encode($arrayJWT, $this->key);

                    $resArray = 
                    [
                        'jwt'=> $encodedJWT,
                        'user_exist'=> 'true', 
                        'user_id'=>$fetchRes['user_id'],  
                        'username'=> $fetchRes['user_name'], 
                        'user_role'=>$fetchRes['role_type']
                    ];

                    $_SESSION['jwt']=$encodedJWT;


                }
                else
                {
                    $resArray = ['user_exist'=> 'false', 'errorMsg' => "Incorrect Password!!!"];
                    //Insert into login_attempt table
                    $sql = "INSERT INTO login_attempt(login_attempt_date, login_attempt_status, user_id)
                            VALUES(:date_time, :attempt_status, :user_id)";
                    $exec = $conn->prepare($sql);
                    $exec->bindValue(':date_time', $this->currentDateTime);
                    $exec->bindValue(':attempt_status', 'Active');
                    $exec->bindValue(':user_id', $exist['user_id']);
                    $exec->execute();
                }
            }
            else
            {
                $resArray = ['user_exist'=> 'false', 'errorMsg' => "Username doesn't exist"];
            }
            return $resArray;
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }



    }
}

在斜边:

login(username, password): Observable<any> {
    let headerOptions = new HttpHeaders();
    //headerOptions.append('Access-Control-Allow-Origin', '*');
    //headerOptions.append('Access-Control-Request-Headers', '*');
    headerOptions.append('Access-Control-Allow-Credentials', 'true');
    headerOptions.append('Content-Type', 'application/json');
    headerOptions.append('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
    headerOptions.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');


    this.credentials = { user: username, pass: password };
    const httpParams = new HttpParams()
      .set('username', username)
      .set('password', password);


    return this.http.post(this.globalVar.login, httpParams, {
      headers: headerOptions,
    })
  }

如您所见,我评论了以下内容:

As you see, I commented the following:

//headerOptions.append('Access-Control-Allow-Origin', '*');
//headerOptions.append('Access-Control-Request-Headers', '*');

在httpd-vhosts.conf上:

At the httpd-vhosts.conf:

# Virtual Hosts
#
<VirtualHost *:80>
  ServerName localhost
  ServerAlias localhost
  DocumentRoot "${INSTALL_DIR}/www"
  <Directory "${INSTALL_DIR}/www/">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    Header set Access-Control-Allow-Origin "*"
    AllowOverride All
    Require local
    Allow from 127.0.0.1
    Allow from 192.168.10.0
    Allow from 192.168.0.217
    Require all granted
  </Directory>
</VirtualHost>


#dev.local
<VirtualHost *:80>

    ServerAdmin it@m.org
    DocumentRoot "c:/wamp64/www/dev"
    ServerName dev.local    
    ServerAlias www.dev.local

    <Directory  "c:/wamp64/www/dev/">

        AllowOverride All
        Require local
        Allow from 127.0.0.1
        #Allow from 192.168.10.0
        #Allow from 192.168.0.140
        Require ip 192.168.0
        Require ip 192.168.1    
        Require ip 192.168.10
        Require all granted     
                Allow from all
    </Directory>
</VirtualHost>

然后我在httpd.conf中启用了mod_headers.

And I enabled the mod_headers in httpd.conf.

我在堆栈上的问题中尝试了解决方案,并且也 answer ,但没有任何变化,仍然出现相同的错误.

I tried the solution from this question on stack, and this answer too, but nothing changed, and still getting the same error.

XHRResponse:

fetch(" http://dev.local/scripts/login.php " , {"credentials":"omit","headers":{"accept":"application/json, 文字/纯文字, /,"内容类型:" application/x-www-form-urlencoded; charset = UTF-8}," referrer:"

fetch("http://dev.local/scripts/login.php", {"credentials":"omit","headers":{"accept":"application/json, text/plain, /","content-type":"application/x-www-form-urlencoded;charset=UTF-8"},"referrer":"http://localhost:4200/login","referrerPolicy":"no-referrer-when-downgrade","body":"username=test&password=test1","method":"POST","mode":"cors"});

推荐答案

在使用后端进行开发时,我已经遇到了很多问题.在服务器上,承载应用程序时,可以使用服务中的URL作为\login而不是http://localhost:8000/login来位于同一域中.

I have faced this problem quite a few times while development with backends. On the server, when your application is hosted, you can be on the same domain by using the url in service as \login instead of http://localhost:8000/login.

对于本地开发,请使用proxy config来运行angular dev服务器.请阅读 https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md 相同.这会将/login的原点从http://localhost:4200更改为http://localhost:8000.

For local development, use proxy config for running angular dev server. Please read https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md for the same. This will change the origin of /login from http://localhost:4200 to http://localhost:8000.

更新:(localhost:8000只是一个示例,您的可能会有所不同) 事实是,浏览器不允许来自混合源(HTTP和HTTPS的混合)和跨源(来自XHR的不同源的数据)的内容.因此,使用代理来欺骗浏览器.

Update: (localhost:8000 is just an example, yours might be different) See the thing is browsers do not allow content from mixed sources (mixture of HTTP and HTTPS) and cross origin (data from different origin for XHR). So proxy is used in order to fool the browser.

您的应用程序正在将\login发送到localhost:4200,并且由于\login API驻留在其中,因此您在angular dev服务器中的代理配置将所有流量路由到\loginlocalhost:8000.但是浏览器将看到您正在向localhost:4200\login发送请求,因此不会再出现CORS问题.您的角度开发服务器将负责路由您的后端API.您只需要添加相同的配置即可.

Your application is sending \login to localhost:4200 and your proxy config in angular dev server is routing all the traffic to \login to localhost:8000 since \login API resides there. But the browser will see the you are sending request to localhost:4200\login so no more CORS issue. Your angular dev server will take care of routing your backend APIs. You just need to add the configurations for the same.

如果您不理解,请随时提出更多疑问.将尝试另一种方法进行解释.

Feel free to ask more doubts, if you dont understand. Will try a different approach to explain.

希望这对您有所帮助.这将消除CORS的问题.

Hopefully this will help you out. This will remove the issues of CORS.

这篇关于Angular和PHP项目"Access-Control-Allow-Origin"标头包含多个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆