Angular和PHP项目"Access-Control-Allow-Origin"标头包含多个值 [英] Angular and PHP project 'Access-Control-Allow-Origin' header contains multiple values
问题描述
我正在开发基于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服务器中的代理配置将所有流量路由到\login
到localhost: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屋!