Pour ce projet, j'apprends et pratique Angular 2. Je n'ai pas de serveur et je fais des demandes d'API à barchart ondemand api .
Je me demande s'il est possible de contourner le problème des cors. Je suis encore assez novice dans ce domaine, alors les instructions étape par étape sont vraiment appréciées! J'utilise http://localhost:8080
.
Message d'erreur: (clé api commentée)
XMLHttpRequest cannot load http://marketdata.websol.barchart.com/getHistory.json?key=MY_API_KEY&symbol=GOOG&type=daily&startDate=20150311000000. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
StockInformationService:
import {Injectable} from 'angular2/core';
import {Http, Headers} from 'angular2/http';
import {Observable} from 'rxjs/Rx';
@Injectable()
export class StockInformationService {
private apiRoot = "http://marketdata.websol.barchart.com/getHistory.json?key=MY_API_KEY&";
constructor (private _http: Http) {}
getData(symbol: string): Observable<any> {
// Tried adding headers with no luck
const headers = new Headers();
headers.append('Access-Control-Allow-Headers', 'Content-Type');
headers.append('Access-Control-Allow-Methods', 'GET');
headers.append('Access-Control-Allow-Origin', '*');
return this._http.get(this.apiRoot + "symbol=" + symbol + "&type=daily&startDate=20150311000000", {headers: headers})
.map(response => response.json());
}
}
Composant d'application:
import {Component} from "angular2/core";
import {VolumeComponent} from '../../components/volume/volume';
import {StockInformationService} from '../../core/stock-information.service';
@Component({
selector: 'app-Shell',
template: require('./app-Shell.html'),
directives: [VolumeComponent],
providers: [StockInformationService]
})
export class AppShell {
constructor(private _stockInformationService: StockInformationService) {}
// In my template, on button click, make api request
requestData(symbol: string) {
this._stockInformationService.getData(symbol)
.subscribe(
data => {
console.log(data)
},
error => console.log("Error: " + error)
)}
}
}
Dans ma console, l'erreur requestData: Error: [object Object]
Ceci est un problème avec la configuration CORS sur le serveur. Vous ne savez pas quel serveur utilisez-vous, mais si vous utilisez Node + Express, vous pouvez le résoudre avec le code suivant
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
ce code était une answer de @jvandemo à une question très similaire.
Vous pouvez en savoir plus à ce sujet à partir d’ici: http://www.html5rocks.com/en/tutorials/cors/ .
Vos méthodes de ressources ne seront pas touchées et leurs en-têtes ne seront jamais configurés. La raison en est qu'il existe ce qu'on appelle une demande de contrôle en amont avant la demande réelle, qui est une demande OPTIONS. Donc l'erreur vient du fait que la requête de contrôle en amont ne produit pas les en-têtes nécessaires . Vérifiez que vous aurez besoin d'ajouter ce qui suit dans votre fichier .htaccess:
Header set Access-Control-Allow-Origin "*"
J'ai également eu le même problème en utilisant http://www.mocky.io/ ce que j'ai fait est d'ajouter l'en-tête de réponse mock.io: Access-Control-Allow-Origin *
Pour l'ajouter il suffit de cliquer sur les options avancées
.__ Une fois que cela est fait, mon application a pu récupérer les données du domaine externe.
Vous pouvez simplement définir dans le fichier php
comme
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
J'ai passé beaucoup de temps à trouver une solution qui fonctionnait enfin en modifiant le serveur. Consultez le site Web https://docs.Microsoft.com/en-us/aspnet/core/security/cors
Cela fonctionnait pour moi lorsque j'ai activé corse côté serveur. Nous utilisions le noyau Asp.Net dans l'API et le code ci-dessous fonctionnait
1) Ajout d’addeurs dans ConfigureServices of Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc();
}
2) Ajout de UseCors dans la méthode Configure comme ci-dessous:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder =>builder.AllowAnyOrigin());
app.UseMvc();
}
Malheureusement, ce n'est pas une erreur Angular2, c'est une erreur de votre navigateur (c'est-à-dire en dehors de votre application).
Cet en-tête CORS devra être ajouté à ce noeud final sur le serveur avant que vous puissiez effectuer TOUTES les demandes.
J'ai également rencontré le même problème et adopté la méthode suivante pour résoudre ce problème.
étape 1:
$ npm install --save-dev http-proxy-middleware
étape 2:
ajoutez un proxy lorsque je récupère une API Web. Si vous utilisez Lite Server, vous pouvez ajouter un fichier bs-config.js.
//file: bs-config.js
var proxyMiddleware = require('http-proxy-middleware');
module.exports = {
server: {
middleware: {
1: proxyMiddleware('/example-api', {
target: 'http://api.example.com',
changeOrigin: true,
pathRewrite: {
'^/news-at-api': '/api'
}
})
}
}
};
j'espère que cela t'aides.
Si vous créez une maquette avec SoapUI , outil de test gratuit pour la demande et la réponse REST et SOAP, vous devez vous rappeler de définir dans votre demande d'en-tête http
Access-Control-Allow-Origin : *
J'ajoute deux images pour vous aider à insérer .. La première montre l'en-tête que vous devez ajouter. Si vous souhaitez ajouter l'en-tête avant de devoir cliquer sur le bouton plus (il est vert).
La deuxième image montre l'insertion du *. La valeur * permet d'accepter toutes les demandes de différents hôtes.
Après ce travail, mon application Angular a supprimé cette erreur gênante dans ma console.
Un grand recours qui m'a aidé à comprendre pour créer ma première maquette est cette vidéo . Cela vous aidera à créer une nouvelle maquette dans l'environnement de SoapUi sans serveur.
J'ai eu le même problème quand je pratiquais Angular5. Ensuite, je suis tombé sur https://spring.io/guides/gs/rest-service-cors/ qui m'a aidé à résoudre le problème.
J'ai gardé @CrossOrigin(exposedHeaders="Access-Control-Allow-Origin")
sur ma méthode de mappage de demandes. Nous pouvons également configurer cela globalement dans l'application de démarrage de printemps.
Un autre moyen simple, sans rien installer
Fonction HTTP
authenticate(credentials) {
let body = new URLSearchParams();
body.set('username', credentials.username);
body.set('password', credentials.password);
return this.http.post(/rest/myEndpoint, body)
.subscribe(
data => this.loginResult = data,
error => {
console.log(error);
},
() => {
// function to execute after successfull api call
}
);
}
Créer un fichier proxy.conf.json
{
"/rest": {
"target": "http://endpoint.com:8080/package/",
"pathRewrite": {
"^/rest": ""
},
"secure": false
}
}
puis ng serve --proxy-config proxy.conf.json
(ou) ouvrez package.json et remplacez
"scripts": {
"start": "ng serve --proxy-config proxy.conf.json",
},
et ensuite npm start
C'est tout.
Vérifiez ici https://webpack.github.io/docs/webpack-dev-server.html pour plus d'options
J'ai la même erreur et voici comment je l'ai résolue en ajoutant ce qui suit à votre contrôleur à ressort:
@CrossOrigin(origins = {"http://localhost:3000"})