Je fais un Ajax.request
à un serveur PHP distant dans une application Sencha Touch 2 (enveloppée dans PhoneGap ).
La réponse du serveur est la suivante:
XMLHttpRequest ne peut pas charger http://nqatalog.negroesquisso.pt/login.php . Origine
http://localhost:8888
n'est pas autorisé par Access-Control-Allow-Origin.
Comment puis-je résoudre ce problème?
J'ai écrit un article sur ce problème il y a quelque temps, Cross Domain AJAX .
Le moyen le plus simple de gérer cela si vous avez le contrôle du serveur répondeur consiste à ajouter un en-tête de réponse pour:
Access-Control-Allow-Origin: *
Cela permettra inter-domaine Ajax . En PHP, vous voudrez modifier la réponse de la manière suivante:
<?php header('Access-Control-Allow-Origin: *'); ?>
Vous pouvez simplement mettre le paramètre Header set Access-Control-Allow-Origin *
dans la configuration de Apache ou le fichier htaccess.
Il convient de noter que cela désactive effectivement la protection CORS, qui expose très probablement vos utilisateurs à des attaques . Si vous ne savez pas que vous devez spécifiquement utiliser un caractère générique, vous ne devez pas l'utiliser, mais vous devez plutôt ajouter à la liste blanche votre domaine spécifique:
<?php header('Access-Control-Allow-Origin: http://example.com') ?>
Si vous n'avez pas le contrôle du serveur, vous pouvez simplement ajouter cet argument à votre Chrome launcher: --disable-web-security
.
Notez que je ne l'utiliserais pas pour la "navigation sur le Web" normale. Pour référence, voir cet article: Désactiver la même politique d'origine dans Chrome .
Si vous utilisez Phonegap pour créer l’application et la charger sur l’appareil, cela ne sera pas un problème.
Si vous utilisez Apache, ajoutez simplement:
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: *
</ifModule>
dans votre configuration. Ainsi, toutes les réponses de votre serveur Web seront accessibles à partir de tout autre site Internet. Si vous souhaitez autoriser uniquement les services de votre hôte à être utilisés par un serveur spécifique, vous pouvez remplacer le *
par l'URL du serveur d'origine:
Header set Access-Control-Allow-Origin: http://my.Origin.Host
Si vous avez une application ASP.NET / ASP.NET MVC , vous pouvez inclure cet en-tête via le fichier Web.config:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<!-- Enable Cross Domain AJAX calls -->
<remove name="Access-Control-Allow-Origin" />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
C’était la première question/réponse qui m’était apparue lorsque je tentais de résoudre le même problème en utilisant ASP.NET MVC comme source de mes données. Je réalise que cela ne résout pas la question PHP , mais elle est suffisamment liée pour être utile.
J'utilise ASP.NET MVC. Le blog de Greg Brant a fonctionné pour moi. En fin de compte, vous créez un attribut, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
, que vous pouvez ajouter aux actions du contrôleur.
Par exemple:
public class HttpHeaderAttribute : ActionFilterAttribute
{
public string Name { get; set; }
public string Value { get; set; }
public HttpHeaderAttribute(string name, string value)
{
Name = name;
Value = value;
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.AppendHeader(Name, Value);
base.OnResultExecuted(filterContext);
}
}
Et puis l'utiliser avec:
[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
return Json( "Some public result" );
}
Matt Mombrea étant correct pour le côté serveur, vous pouvez rencontrer un autre problème, à savoir le rejet en liste blanche.
Vous devez configurer votre phonegap.plist. (J'utilise une ancienne version de phonegap)
Pour Cordova, il se peut que certaines modifications soient apportées à la dénomination et au répertoire. Mais les étapes devraient être essentiellement les mêmes.
Commencez par sélectionner Fichiers de support> PhoneGap.plist
puis sous "ExternalHosts"
Ajoutez une entrée, avec une valeur de peut-être " http://nqatalog.negroesquisso.pt " J'utilise * uniquement à des fins de débogage.
Je l'ai rencontré à quelques reprises lorsque je travaillais avec différentes API. Une solution rapide consiste souvent à ajouter "& callback =?" à la fin d'une chaîne. Parfois, l'esperluette doit être un code de caractère et parfois un "?": "? Callback =?" (voir tilisation de l'API Forecast.io avec jQuery )
Cela peut être pratique pour ceux qui ont besoin d'une exception pour les versions "www" et "non-www" d'un référent:
$referrer = $_SERVER['HTTP_REFERER'];
$parts = parse_url($referrer);
$domain = $parts['Host'];
if($domain == 'google.com')
{
header('Access-Control-Allow-Origin: http://google.com');
}
else if($domain == 'www.google.com')
{
header('Access-Control-Allow-Origin: http://www.google.com');
}
Je vais vous donner une solution simple pour celui-ci. Dans mon cas, je n'ai pas accès à un serveur. Dans ce cas, vous pouvez modifier la stratégie de sécurité de votre navigateur Google Chrome pour autoriser Access-Control-Allow-Origin. C'est très simple:
Coller simple dans "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security
.
L'emplacement peut différer. Maintenant, ouvrez Chrome en cliquant sur ce raccourci.
Si vous écrivez une extension Chrome et obtenez cette erreur, assurez-vous d'avoir ajouté l'URL de base de l'API à votre manifest.json
' bloc d'autorisations , exemple:
"permissions": [
"https://iTunes.Apple.com/"
]
si vous êtes sous Apache, ajoutez simplement un fichier .htaccess à votre répertoire avec ce contenu:
Header set Access-Control-Allow-Origin: *
Header set Access-Control-Allow-Headers: content-type
Header set Access-Control-Allow-Methods: *
Si vous obtenez ceci dans Angular.js, assurez-vous d'échapper à votre numéro de port comme ceci:
var Project = $resource(
'http://localhost\\:5648/api/...', {'a':'b'}, {
update: { method: 'PUT' }
}
);
Voir ici pour plus d'informations à ce sujet.
Vous pouvez le faire fonctionner sans modifier le serveur en faisant en sorte que le navigateur incluant l'en-tête Access-Control-Allow-Origin: *
dans les réponses HTTP OPTIONS '.
Sous Chrome, utilisez cette extension . Si vous êtes sur Mozilla, vérifiez cette réponse .
C'est à cause de politique de même origine . Voir plus sur Réseau de développeurs Mozilla ou Wikipedia .
Fondamentalement, dans votre exemple, vous devez charger la page http://nqatalog.negroesquisso.pt/login.php
uniquement à partir de nqatalog.negroesquisso.pt
et non pas localhost
.
Dans Ruby on Rails , vous pouvez faire dans un contrôleur:
headers['Access-Control-Allow-Origin'] = '*'
Nous avons également le même problème avec l'application phonegap testée en chrome. Nous utilisons tous les jours ci-dessous un fichier batch avant d’ouvrir Chrome. N'oubliez pas qu'avant d'exécuter cette opération, vous devez nettoyer toutes les instances de chrome du gestionnaire de tâches ou vous pouvez sélectionner chrome pour ne pas l'exécuter en arrière-plan.
BATCH: (utilisez cmd)
cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security
Dans Ruby Sinatra
response['Access-Control-Allow-Origin'] = '*'
pour tout le monde ou
response['Access-Control-Allow-Origin'] = 'http://yourdomain.name'
Lorsque vous recevez la demande, vous pouvez
var Origin = (req.headers.Origin || "*");
que lorsque vous devez répondre aller avec quelque chose comme ça:
res.writeHead(
206,
{
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': Origin,
}
);