comment contourner Access-Control-Allow-Origin?

je fais un appel ajax à mon propre serveur sur une plate-forme qu'ils mettent empêcher ces appels ajax (mais j'en ai besoin pour récupérer les données de mon serveur pour afficher les données récupérées à partir de la base de données de mon serveur). Mon script ajax fonctionne , il peut envoyer les données au script php de mon serveur pour lui permettre de traiter. Toutefois, il ne peut pas récupérer les données traitées car il est bloqué par "Access-Control-Allow-Origin"

Je n'ai pas accès à la source/core de cette plateforme. donc je ne peux pas enlever le script qu'il me refusant à le faire. (P/S j'ai utilisé la Console de Google Chrome et découvert cette erreur)

le code Ajax comme indiqué ci-dessous:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });

ou est-il un JSON code équivalent à l'ajax script ci-dessus ? Je pense que JSON est autorisé.

j'espère que quelqu'un pourrait m'aider.

164
demandé sur Ram Patra 2011-09-27 10:03:12

8 réponses

mettre sur le dessus de la récup.php

 header('Access-Control-Allow-Origin: *');  

il est important de noter que le header() doit être appelé avant toute sortie réelle est envoyé.

Mauvais

<html>
<?php
header('Access-Control-Allow-Origin: *'); 
?>

Correct

<?php
header('Access-Control-Allow-Origin: *'); 
?>
<html>
326
répondu Rafay 2017-08-02 17:48:29

D'accord, mais vous savez tous que le * est un joker et permet le script cross site de chaque domaine?

vous souhaitez envoyer plusieurs en - têtes Access-Control-Allow-Origin pour chaque site qui est autorisé à-mais malheureusement son officiellement pas pris en charge pour envoyer plusieurs en-têtes Access-Control-Allow-Origin , ou de mettre dans des origines multiples.

vous pouvez résoudre cela en vérifiant l'origine, et en renvoyant celle-ci dans l'en-tête, si elle est autorisée:

$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}

C'est plus sûr. Vous pouvez éditer la correspondance et la changer en une fonction manuelle avec un certain regex, ou quelque chose comme ça. Au moins ceci ne renverra qu'un en-tête, et vous serez sûr que c'est celui d'où provient la requête. Veuillez noter que tous les en-têtes HTTP peuvent être mystifiés, mais cet en-tête est pour la protection du client. Ne protégez pas vos propres données avec ces valeurs. Si vous voulez en savoir plus, lisez un peu sur CORS et CSRF.

Pourquoi est-ce plus sûr?

permettant l'accès à partir d'autres emplacements puis votre propre site de confiance permet le highjacking de session. Je vais prendre un petit exemple-image Facebook permet une origine Joker - cela signifie que vous pouvez faire votre propre site Web quelque part, et le faire feu appels AJAX (ou ouvrir iframes) à facebook. Cela signifie que vous pouvez saisir les informations enregistrées dans le facebook d'un visiteur de votre site web. Pire, vous can script POST demandes et afficher des données sur facebook de quelqu'un - juste pendant qu'ils naviguent sur votre site web.

soyez très prudent lorsque vous utilisez les en-têtes ACAO !

251
répondu Rob Quist 2018-08-01 09:59:59

Warning , Chrome (et d'autres navigateurs) se plaindra que plusieurs en-têtes ACAO sont définis si vous suivez certaines des autres réponses.

l'erreur sera quelque chose comme XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

essayez ceci:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}
25
répondu 2017-01-10 12:00:14

j'ai corrigé ce problème en appelant un contrôleur MVC3. J'ai ajouté:

Response.AddHeader("Access-Control-Allow-Origin", "*"); 

avant mon

return Json(model, JsonRequestBehavior.AllowGet);

et aussi mon $.ajax se plaignait qu'il n'accepte pas Type de contenu en-tête dans mon appel ajax, donc je l'ai commenté comme je sais son JSON étant passé à l'Action.

Espère que ça aide.

7
répondu Atif Rehman 2012-03-19 14:14:33

le mieux serait d'autoriser les domaines simples, soyez prudent sur le http://:

     header('Access-Control-Allow-Origin: http://www.foo.com', false);
     header('Access-Control-Allow-Origin: http://www.foo2.com', false));
6
répondu Sebastian Viereck 2016-11-26 10:03:06

avez-vous essayé d'ajouter l'en-tête Access-Control-Allow-Origin à la réponse envoyée depuis votre serveur? Comme Access-Control-Allow-Origin: * ?

3
répondu Daniel Brockman 2011-09-27 06:07:44

c'est une très mauvaise idée d'utiliser * , ce qui vous laisse largement ouvert aux scripts de sites croisés. Vous voulez fondamentalement votre propre domaine tout le temps, scopé à vos paramètres SSL actuels, et éventuellement des domaines supplémentaires. Vous voulez aussi qu'ils soient tous envoyés en un seul en-tête. Ce qui suit autorisera toujours votre propre domaine dans la même portée SSL que la page actuelle, et peut éventuellement inclure n'importe quel nombre de domaines supplémentaires. Il les enverra tous comme un en-tête, et écrasera le (s) précédent (s) si quelque chose d'autre les a déjà envoyé (s) pour éviter que le navigateur ne se plaignent de l'envoi de plusieurs en-têtes de contrôle d'accès.

class CorsAccessControl
{
    private $allowed = array();

    /**
     * Always adds your own domain with the current ssl settings.
     */
    public function __construct()
    {
        // Add your own domain, with respect to the current SSL settings.
        $this->allowed[] = 'http'
            . ( ( array_key_exists( 'HTTPS', $_SERVER )
                && $_SERVER['HTTPS'] 
                && strtolower( $_SERVER['HTTPS'] ) !== 'off' ) 
                    ? 's' 
                    : null )
            . '://' . $_SERVER['HTTP_HOST'];
    }

    /**
     * Optionally add additional domains. Each is only added one time.
     */
    public function add($domain)
    {
        if ( !in_array( $domain, $this->allowed )
        {
            $this->allowed[] = $domain;
        }
    /**
     * Send 'em all as one header so no browsers grumble about it.
     */
    public function send()
    {
        $domains = implode( ', ', $this->allowed );
        header( 'Access-Control-Allow-Origin: ' . $domains, true ); // We want to send them all as one shot, so replace should be true here.
    }
}

Utilisation:

$cors = new CorsAccessControl();

// If you are only authorizing your own domain:
$cors->send();

// If you are authorizing multiple domains:
foreach ($domains as $domain)
{
    $cors->add($domain);
}
$cors->send();

vous comprenez.

0
répondu mopsyd 2018-04-23 01:16:02

si vous testez à partir de localhost, vous pouvez également utiliser:

header('Access-Control-Allow-Origin: http://localhost:8080', false); où 8080 est le port que vous testez.

0
répondu Philip D. 2018-07-15 15:57:50