Comment résoudre Cross-Origin-Demande-Bloc de problème lors de la récupération des données en utilisant angular2 et php?
Veuillez lire la question en détail, puisqu'il est long, avec diverses modifications et de l'étendue des mises à jour selon la demande des autres utilisateurs.
Je suis en train d'envoyer des données au fichier php à l'aide de angular2. Je suis en train de faire l'angulaire du projet d'Unix et de la var/www/html/
est le php Xampp emplacements de dossier pour l'exécution, les fichiers php.
Ma structure de dossier comme ceci:-
var/www/html/
|_(angproject)
|_(phpscript)
| |_login.php
|_(src)
|_(app)
|_(admin)
| |_(login)
| | |_login.component.ts
| |
| |_admin.component.ts
|
|_(_admin_service)
| |_admin.login.ts
|
|_(_animations)
|
|_(front)
|
|_(_models)
| |_admin.model.ts
|
|_app.module.ts
Mon app.le module.ts fichier comme ceci:-
import { HttpModule, Http, Response, Headers, RequestOptions} from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { APP_BASE_HREF } from '@angular/common';
import { CanActivate } from "@angular/router";
import { AppComponent } from './app.component';
import { FrontComponent } from './front/front.component';
import { AdminComponent } from './admin/admin.component';
import { LoginComponent } from './admin/login/login.component';
import { DashboardComponent } from './admin/dashboard/dashboard.component';
import { HeaderComponent } from './admin/header/header.component';
import { FooterComponent } from './admin/footer/footer.component';
import { LeftmenuComponent } from './admin/leftmenu/leftmenu.component';
import { NavbarComponent } from './admin/navbar/navbar.component';
import { ShortcutbarComponent } from './admin/shortcutbar/shortcutbar.component';
import { AdminLoginService } from './_admin_service/admin.login';
const appRoutes: Routes = [
{ path: 'admin',
component: AdminComponent,
children: [
{ path: '', component: LoginComponent},
{ path: 'dashboard', component: DashboardComponent}
]
}
];
@NgModule({
declarations: [
AppComponent,
FrontComponent,
AdminComponent,
LoginComponent,
DashboardComponent,
HeaderComponent,
FooterComponent,
LeftmenuComponent,
NavbarComponent,
ShortcutbarComponent
],
imports: [
HttpModule,
HttpClientModule,
BrowserModule,
BrowserAnimationsModule,
FormsModule,
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } //<-- debugging purposes only
)
],
providers: [{provide: APP_BASE_HREF, useValue : '/' },AdminLoginService],
bootstrap: [AppComponent]
})
export class AppModule { }
Mon de connexion.composante.ts fichier est: est-ce-
import { Component, OnInit, Input } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { fadeInAnimation } from '../../_animations/index';
import { Admin } from '../../_models/admin.model';
import { AdminLoginService } from '../../_admin_service/admin.login';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
animations: [fadeInAnimation],
host: { '[@fadeInAnimation]': '' },
providers: [AdminLoginService]
})
export class LoginComponent implements OnInit {
loading = false;
returnUrl: string;
responseStatus:Object= [];
status:boolean ;
//@Input() admin:Admin;
model = new Admin('', '', '', 'Emailsss','Passwordsss');
constructor(
private route: ActivatedRoute,
private router: Router,
private _adminLogin: AdminLoginService
){}
submitPost()
{
//console.log("submit Post click happend " + this.model.email)
//console.log(this.model);
this._adminLogin.postLogin(this.model).subscribe(
data => console.log(this.responseStatus = data),
err => console.log(err),
() => console.log('Request Completed')
);
this.status = true;
}
ngOnInit() {
}
}
Le service de fichier admin.connexion.ts fichier est: est-ce-
import { Http, Response, Headers, RequestOptions} from '@angular/http';
import { HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { Admin } from '../_models/admin.model';
@Injectable()
export class AdminLoginService {
http : Http;
actionUrl : string;
admin_login_Url: string;
postData: Admin;
constructor(public _http: Http) {
this.http = _http;
this.admin_login_Url = 'http://localhost/angproject/phpscript/login.php';
}
postLogin(postData:Admin) {
let headers = new Headers();
headers.append("Access-Control-Allow-Origin","*");
headers.append("Access-Control-Allow-Methods","GET, POST");
headers.append("Content-Type","application/json");
let options = new RequestOptions({ headers: headers });
console.log(postData);
this.actionUrl = this.admin_login_Url;
return this.http.post(this.actionUrl, {postData}, options)
.map(res => res.json());
}
}
Et finalement, mon login.php le fichier est présent:-
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST");
header("Access-Control-Allow-Headers: *");
header("Content-Type: application/json; charset=utf-8");
include('connection.php');
$rawData = file_get_contents("php://input");
$data = json_decode($rawData, true);
$error = array();
if(isset($data['postData']['email']) && !empty($data['postData']['email']))
$email = $data['postData']['email'];
else
$error[] = "Email was not entered";
if(isset($data['postData']['password']) && !empty($data['postData']['password']))
$password = $data['postData']['password'];
else
$error[] = "Password was not entered";
if(empty($error))
{
$runQuery = "SELECT * FROM users WHERE email = '$email' AND password = '$password'";
$result = $conn->query($runQuery);
if ($result->num_rows > 0)
{
$response['status'] = 1;
$response['message'] = "Login successfully";
$response['error'] = 0;
}
else
{
$response['status'] = 0;
$response['message'] = "An error occured while logging in";
$response['error'] = $conn->error;
}
}
else
{
$response['status'] = 0;
$response['message'] = "Parameter missing";
$response['error'] = $error;
}
$respond = json_encode($response);
echo $respond;
exit;
?>
Maintenant, ici, est le problème. Lors de l'essai de Chrome, en cliquant sur le bouton "soumettre" une fois la cuisson, appelant le script php (Ajax) deux fois. Le premier appel de ne pas envoyer de données et, par conséquent, il affiche un message de validation en retour de réponse. Le deuxième appel envoie les données du formulaire et donc de récupérer le résultat souhaité par la mise en correspondance des données envoyées.
Dans le cas de firefox, j'obtiens cette réponse:-
Comment puis-je le résoudre?
Note:
Ici sont les en-Têtes de Requête de "premier appel" dans chrome:
Ici sont les en-Têtes de Requête de "deuxième appel" dans google chrome:
EDIT: Daté - 04-04-2018:
Que par les suggestions de David, j'ai fait des changements ultérieurs dans mon login.php fichier:
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Headers: application/x-www-form-urlencoded");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
Dans l'admin.connexion.fichier ts, j'ai fait les modifications suivantes:-
postLogin(postData:Admin) {
let headers = new Headers();
headers.append("Accept", "q=0.8;application/json;q=0.9");
this.actionUrl = this.admin_login_Url;
return this.http.post(this.actionUrl, {postData}, { headers: headers })
.map(res => res.json()).share();
}
}
Question 1:
Pour le code ci-dessus, j'ai pris de référence à partir de ce site. Pourtant, j'ai toujours l'erreur. Comment puis-je résoudre ce problème dans Firefox?
Dans le code ci-dessus, j'ai ajouté la ligne headers.append("Accept", "q=0.8;application/json;q=0.9");
à surmonter une erreur indiqué ci-dessous:-
Comment puis-je résoudre ce problème?
Question 2:
Dans Firefox, la console lit:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/angproject/phpscript/register.php. (Reason: invalid token ‘application/x-www-form-urlencoded’ in CORS header ‘Access-Control-Allow-Headers’).
Lors de la vérification dans Chrome, je peux voir deux appels dans l'onglet réseau de la console. Le premier appel du type de demande est des OPTIONS, tandis que le deuxième appel a requête de type POST.
Dans le cas de Firefox, j'obtiens un seul appel avec le type de la demande OPTIONS. La requête POST n'est pas de prendre place à tous.
Comment puis-je résoudre ce problème?
- il y a un plugin chrome pour le fixer sur local dev env
- Quelqu'un soin d'expliquer pourquoi le downvote? Ce n'est pas comme je suis la mendicité pour les points, mais j'apprécierais si quelqu'un peut expliquer l'erreur dans la question.
- Pouvez-vous afficher les en-têtes de réponse pour la demande d'options dans votre chrome débogueur? Et qui serveur web utilisez-vous
- Assurez-vous. Donnez-moi un peu de temps pour modifier la question.
- J'ai ajouté les en-têtes de requête
- Ce sont les en-têtes de la requête POST, pouvez-vous afficher les en-têtes pour les OPTIONS de demande? (la première)
- Les en-Têtes de la OPTIONS des requêtes sont également fournis, juste en dessous de la ligne de
Here are the Request Headers of the "first call" in chrome:
- Désolé, je n'ai pas compris: Que si vous essayez
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
- Même problème. Doens pas résoudre mon erreur.
- Laissez-nous continuer cette discussion dans le chat.
Vous devez vous connecter pour publier un commentaire.
Avoir 2 demandes est normal, en raison de la SCRO mise en œuvre (client sur
localhost:4200
, serveur surlocalhost
= différents ports).https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Votre problème est que vous avez spécifié certaines catégories de documents des en-têtes dans votre demande
Ces en-têtes sont destinés à être ajoutés côté serveur, vous n'avez pas besoin de les envoyer angulaires. Ils sont en fait à l'origine du problème.
Les supprimer et cela devrait fonctionner.
Plus d'informations sur Access-Control-Allow-en-Têtes de
Access-Control-Allow-Headers
accepte normalement une liste séparée par des virgules des en-têtes.https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
Le caractère générique (*) la valeur que vous avez dans votre code PHP n'est pas pris en charge sur tous les navigateurs. Sur Firefox, le générique n'est pas encore implémenté
https://bugzilla.mozilla.org/show_bug.cgi?id=1309358
C'est pourquoi firefox est bloking votre POST, depuis le contrôle en amont (OPTIONS) de demande type de l'échec de
Vous n'avez pas besoin de spécifier
Content-Type
dans votre liste, car il est accepté par défautModifier: en fait, vous avez besoin de spécifier le type de contenu dans la liste des accepté les en-têtes depuis que vous êtes à l'envoi de
application/json
, ce qui n'est pas dans la liste ci-dessusEXCEPTION: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
application/x-www-form-urlencoded
comme un permis de l'en-tête? Ce n'est pas un en-tête, c'est une valeur !!! D'ailleurs, c'est la valeur de laContent-Type
en-tête, ce qui n'est PAS nécessaire dans la liste, comme indiqué ci-dessus au jaune. Juste retirer votreAccess-Control-Allow-Headers
, et ajouter si firefox se plaint toujours. SI vous le faites, il suffit d'ajouter la liste de NOMS d'en-tête (et non pas les valeurs)header("Access-Control-Allow-Headers: *");
causes d'erreur dans le navigateur Chrome, qui donne le message:Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
header("Access-Control-Allow-Headers: *");
provoque une erreur dans Firefox qui donne du message:Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/angproject/phpscript/login.php. (Reason: missing token ‘content-type’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
header("Access-Control-Allow-Headers: content-type");
alorsJ'ai eu le même problème lors de l'exécution de la angulaire de l'app sur google chrome navigateur dans windows. Même moi, je le programme d'installation de la SCRO configuration dans un backend que le problème n'est pas résolu. Puis je me rends compte que j'ai besoin de désactiver la sécurité du web lors de l'exécution sur une machine locale ou
Suffit de cliquer sur la commande suivante sur cmd
Cela a résolu mon problème 🙂