Déclencher une AJAX GET
en http://qualifiedlocalhost:8888/resource.json
déclenche le pré-vol attendu du CORS, qui semble bien revenir:
OPTIONS
avant le volRequest URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK
En-têtes de demande
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, Origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
En-têtes de réponse
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express
Donc ça devrait marcher, non?
Mais la requête suivante échoue toujours avec l'erreur XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
Request URL:http://qualifiedlocalhost:8888/resource.json
En-têtes de demande
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest
Peut-être qu'il regarde juste devant moi. Mais, des idées? Juste au cas où cela serait pertinent ... J'utilise un $resource
AngularJS et je parle à un serveur CompoundJS.
changer vos méthodes d'accès-contrôle-autoriser: 'GET, POST' à 'GET, POST, PUT, DELETE'
avant:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
Après:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
J'ai récemment eu le même problème . Le problème est que l'en-tête Access-Control-Allow-Origin
(et, si vous l'utilisez, l'en-tête Access-Control-Allow-Credentials
) doit être envoyé dans both la réponse de contrôle en amont et la réponse réelle.
Votre exemple ne l’a que dans la réponse de contrôle en amont.
Est-ce que votre fonction serveur/get Web inclut AUSSI l'en-tête HTTP: Access-Control-Allow-Origin? J'ai finalement trouvé le succès avec cet ajout, en utilisant AngularJS 1.0.7 et un servlet Java distant. Voici mon extrait de code Java - aucune modification n'a été requise dans le client AngularJS:
Servlet:
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Send Response
super.doOptions(request, response);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* ... */
response.setHeader("Access-Control-Allow-Origin", "*");
}
Une alternative plus élégante est un filtre de servlet.
Nous avons remarqué le même problème, où le serveur envoie les en-têtes CORS corrects, mais le navigateur échoue car il pense que les exigences CORS ne sont pas satisfaites. Plus intéressant encore, dans notre cas, cela ne se produit que sur certains appels AJAX dans la même session de navigateur, mais pas tous.
Effacer le cache du navigateur résout le problème dans notre cas - Ma théorie de travail actuelle est que cela a quelque chose à voir avec les cookies installés par le serveur cross Origin. J'ai remarqué que dans votre scénario, un cookie est défini dans le cadre de la réponse à la demande OPTIONS avant le vol. Avez-vous essayé de faire en sorte que ce serveur ne mette pas de cookies pour les demandes provenant d'une origine différente?
Cependant, nous avons remarqué que, dans certains cas, le problème réapparaissait après la réinitialisation du navigateur. De plus, si vous exécutez le navigateur en mode privé, le problème disparaît, ce qui indique un problème lié au contenu du cache du navigateur.
Pour référence, voici mon scénario (j'ai presque posté ceci comme une nouvelle question dans SO, mais le mettant ici à la place):
Nous avons rencontré un bogue dans lequel certaines requêtes CORS GET effectuées via jQuery.ajax échouaient. Dans une session de navigateur donnée, nous voyons la demande OPTIONS pré-vol passer, suivie de la demande réelle. Dans la même session, certaines demandes sont traitées et d'autres échouent.
La séquence de demandes et de réponses dans la console réseau du navigateur se présente comme suit:
D'abord la demande de pré-vol OPTIONS
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, Origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Ce qui obtient une réponse comme,
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, Origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Ensuite, la demande GET réelle,
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
Qui obtient une erreur dans la console du navigateur comme,
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
Débogage supplémentaire
Je peux rejouer la même séquence via curl et je vois des réponses valables venant du serveur. c'est-à-dire qu'ils ont les en-têtes CORS attendus qui devraient laisser passer les demandes.
L'exécution du même scénario dans une fenêtre de navigateur privée/incognito ne reproduisait pas le problème. Cela m’a amené à essayer de vider la mémoire cache, ce qui a également permis de résoudre le problème. Mais après un moment, il est revenu.
Le problème se reproduisait sur un safari sur iPhone ainsi que sur Chrome sur le bureau OSX.
Ce dont j'ai vraiment besoin d'aide
Je soupçonne que certains cookies installés dans le domaine cross-Origin sont impliqués et sont susceptibles de révéler un bogue dans le navigateur. Existe-t-il des outils ou des points d'arrêt que je peux définir dans le navigateur (pile native?) Pour essayer de déboguer davantage? Un point d'arrêt dans le code qui évalue la stratégie CORS serait idéal.
utiliser le module cors pour éviter le problème
var cors = require('cors')
var app = express()
app.use(cors())
On dirait que votre réponse aux "options" fonctionne bien. Le problème semble être dans la réponse «obtenir».
Vous voudrez que votre réponse «get» renvoie les mêmes en-têtes CORS que la réponse «options».
En particulier, la réponse «get» devrait inclure
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*