Como funciona o cabeçalho Access-Control-Allow-Origin?

Aparentemente, percebi mal a sua semântica. Pensei em algo assim:
  1. um cliente transfere o código javascript MyCode.JS de http://siteA - a origem.
  2. o cabeçalho de resposta do MyCode.js contains Access-Control-Allow-Origin: http://siteB o que eu pensava que significava o meu código.a js foi autorizada a fazer referências de origem cruzada ao site B.
  3. o cliente acciona alguma funcionalidade do MyCode.js, que por sua vez pedidos de http://siteB, o que deve ser bom, apesar de serem pedidos de origem cruzada.
Bem, estou errado. Não funciona assim. Então, eu li A partilha de recursos de origem cruzada e tentei ler A partilha de recursos de origem cruzada na Recomendação w3c

Uma coisa é certa-eu ainda não entendo como devo usar este cabeçalho.

Tenho o controlo total do site a e do site B. Como é que activo o código javascript baixado do site a para acessar recursos no site B usando este cabeçalho?

P. S.

Não quero utilizar o JSONP.

Author: Sujania, 2012-05-17

11 answers

Access-Control-Allow-Origin is a CORS (Cross-Origin Resource Sharing) header .

Quando o Site a tenta obter o conteúdo do Site B, O Site B pode enviar um cabeçalho de resposta Access-Control-Allow-Origin para dizer ao navegador que o conteúdo desta página está acessível a certas origens. (Uma origem é um domínio , mais um esquema e número de Porto .) Por omissão, as páginas do 'Site B' não estão acessíveis a qualquer outra origem {[[29]}; usando o cabeçalho Access-Control-Allow-Origin abre uma porta para o acesso de origem cruzada por: origens específicas.

Para cada recurso / página que o Site B quer tornar acessível ao Site a, o Site B deve servir as suas páginas com o cabeçalho de resposta:

Access-Control-Allow-Origin: http://siteA.com

Os navegadores modernos não irão bloquear os pedidos de domínio cruzado. Se o Site a solicitar uma página do Site B, o navegador irá realmente obter a página solicitada no nível da rede e verificar se os cabeçalhos de resposta listam o Site a como um domínio de requisição permitido. Se o local B não tiver indicado que o Local A é ao aceder a esta página, o navegador activará o evento XMLHttpRequest's error e negará os dados de resposta ao código JavaScript que o solicita.

Pedidos não simples

O Que Acontece a nível da rede pode ser ligeiramente mais complexo do que explicado acima. Se o pedido for um pedido" não-simples " , o navegador envia primeiro um pedido de opções "pré-voo" sem dados, para verificar se o servidor irá aceitar o pedido. Um pedido não é simples quando (ou ambos):

  • usando um verbo HTTP diferente do GET ou POST (PUT, DELETE)
  • Usando cabeçalhos de pedidos não simples; os únicos cabeçalhos de pedidos simples são::
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (isto só é simples quando o seu valor é application/x-www-form-urlencoded, multipart/form-data, ou text/plain)

Se o servidor responder às opções pré-iluminadas com cabeçalhos de resposta apropriados (Access-Control-Allow-Headers para cabeçalhos não-Simples, Access-Control-Allow-Methods para verbos não-simples) que corresponder ao verbo não-simples e/ou aos cabeçalhos não-simples, em seguida, o navegador envia o pedido real.

Supondo que o Site a queira enviar um pedido de PUT para /somePage, com um valor não simples Content-Type de application/json, o navegador enviaria primeiro um pedido de pré-voo:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Note que Access-Control-Request-Method e Access-Control-Request-Headers são adicionados automaticamente pelo navegador; você não precisa adicioná-los. Estas opções pré-realçam os cabeçalhos de resposta com sucesso:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

Ao enviar o pedido real (após o pré-voo ser feito), o comportamento é idêntico à forma como uma simples solicitação é tratada. Em outras palavras, um pedido não-simples cujo pré-voo é bem sucedido é tratado da mesma forma que um simples pedido (ou seja, o servidor ainda deve enviar Access-Control-Allow-Origin novamente para a resposta real).

Os navegadores enviam o pedido real:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

E o servidor envia um Access-Control-Allow-Origin, tal como faria para um simples pedido:

Access-Control-Allow-Origin: http://siteA.com

Ver compreender o XMLHttpRequest sobre o CORS para um um pouco mais de informação sobre pedidos não-simples.

 1060
Author: apsillers, 2017-05-23 11:47:28

Cross-Origin Request Sharing - CORS (A. K. A. Cross-Domain AJAX request) é um problema que a maioria dos desenvolvedores da web pode encontrar, de acordo com a mesma Política de origem, navegadores restringir JavaScript cliente em uma caixa de segurança, normalmente JS não pode se comunicar diretamente com um servidor remoto de um domínio diferente. No passado, os desenvolvedores criaram muitas maneiras complicadas para alcançar o pedido de recursos Cross-Domain, mais comumente usando maneiras são:

  1. usar o Flash/Silverlight ou o lado do servidor como um "proxy" para comunicar com controlo remoto.
  2. JSON com enchimento (JSONP ).
  3. incorpora um servidor remoto numa iframe e comunica através do fragmento ou window.name, veja Aqui.

Essas maneiras complicadas têm mais ou menos alguns problemas, por exemplo JSONP pode resultar em Buraco de segurança se os desenvolvedores simplesmente "eval" ele, e #3 acima, embora funcione, ambos os domínios devem construir um contrato estrito entre os outros, ele nem flexível nem elegante IMHO:)

O W3C tinha introduzido o Cross-Origin Resource Sharing (CORS) como uma solução padrão para fornecer uma forma segura, flexível e recomendada de resolver este problema.

O Mecanismo

A partir de um nível elevado, podemos simplesmente considerar que o CORS é um contrato entre o cliente AJAX call do domínio a e uma página hospedada no domínio B, um pedido de origem cruzada típico / resposta seria:

Domaina AJAX pede cabeçalhos

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

Resposta do DomainB cabeçalhos

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

As partes azuis eu marcados acima foram o kernel fatos, a "Origem" do cabeçalho de solicitação "indica onde o cruz-solicitação de origem ou de comprovação de pedido originário do", "Access-Control-Allow-Origin" cabeçalho de resposta indica esta página permite a solicitação remota do Domínioa (se o valor é * indicar permite a pedidos remotos de qualquer domínio).

Como mencionei acima, o W3 recomendou o navegador para implementar um "pedido de pré-voo " antes de submeter o Pedido HTTP de origem cruzada, em poucas palavras é um pedido HTTP OPTIONS:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

Se foo.o aspx suporta as opções do verbo HTTP, podendo responder como em baixo:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

Só se a resposta contiver "Access-Control-Allow-Origin" e o seu valor for "*" ou conter o domínio que submeteu o pedido do CORS, ao satisfazer este navegador de condições mandtory irá submeter o pedido de Cross-Domain real, e guardar o resultado em "Preflight-Result-Cache".

Eu blogei sobre CORS há três anos: pedido HTTP de origem cruzada AJAX
 104
Author: Wayne Ye, 2016-07-28 09:01:23

A pergunta é um pouco velha demais para responder, mas estou a postar isto para qualquer referência futura a esta pergunta.

De acordo com Este Artigo da rede de desenvolvimento Mozilla,

Um recurso faz um pedido HTTP de origem cruzada quando ele pede um recurso de um domínio diferente, ou porto do que aquele que o primeiro recurso em si serve.

enter image description here

AnHTML page served from http://domain-a.com makes an <img> pedido src para http://domain-b.com/image.jpg.
Muitas páginas na web carregam hoje recursos como as 'stylesheets' de CSS, imagens e scripts de domínios separados (por isso deve ser fixe).

Mesma Política De Origem

Por razões de segurança, os navegadores restringem Os pedidos de origem cruzada HTTP iniciados a partir de scripts.
Por exemplo, XMLHttpRequest e Fetch seguem a Política de mesma origem.
Assim, uma aplicação web usando XMLHttpRequest ou Fetch poderia apenas faça pedidos HTTP para o seu próprio domínio .

Partilha de recursos de origem cruzada (CORS)

Para melhorar as aplicações web, os programadores pediram aos fornecedores de browser que permitissem pedidos de cross-domain.

O mecanismo Cross-Origin Resource Sharing (CORS) dá os servidores web cross-domain access controls, que permitem a transferência segura de dados cross-domain.
Os navegadores modernos utilizam CORS num recipiente de API - tais como XMLHttpRequest ou Fetch - para atenuar os riscos de pedidos de origem cruzada HTTP.

Como funciona o CORS (Access-Control-Allow-Origin cabeçalho)

Wikipédia:

A norma CORS descreve novos cabeçalhos HTTP que fornecem navegadores e Servidores uma forma de pedir URLs remotos Apenas quando eles têm permissão.

Embora alguma validação e autorização possa ser realizada pelo servidor, é geralmente da responsabilidade do navegador para suportar estes cabeçalhos e honrar o restrições que impõem.

Exemplo

  1. O navegador envia o pedido OPTIONS com um cabeçalho Origin HTTP.

    O valor deste cabeçalho é o domínio que serviu a página pai. Quando uma página de http://www.example.com tenta aceder aos dados de um utilizador em service.example.com, o seguinte cabeçalho de pedido será enviado para service.example.com:

    Origem: http://www.example.com

  2. O servidor em service.example.com pode responder com:

    • Cabeçalho Access-Control-Allow-Origin (ACAO) na sua resposta, indicando quais os sítios de origem que são permitidos.
      Por exemplo:

      Access-Control-Allow-Origin: http://www.example.com

    • Uma página de erro se o servidor não permitir o pedido de origem cruzada

    • Um cabeçalho Access-Control-Allow-Origin (ACAO) com uma placa especial que permite todos os domínios:

      Access-Control-Allow-Origin: *

 35
Author: Trix, 2017-03-05 06:39:53

Se quiser apenas testar uma aplicação de domínio transversal na qual o navegador Bloqueia o seu pedido, então pode apenas abrir o seu navegador em modo inseguro e testar a sua aplicação sem alterar o seu código e sem tornar o seu código inseguro. Do MAC OS você pode fazer isso a partir da linha terminal:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
 7
Author: Maurizio Brioschi, 2017-02-22 16:32:30

Usando React e Axios , junte a ligação 'proxy' ao URL e adicione o cabeçalho como mostrado abaixo

https://cors-anywhere.herokuapp.com/ + Your API URL

Apenas adicionando o link do Proxy irá funcionar, mas também pode lançar erro para nenhum acesso novamente. Assim, é melhor adicionar cabeçalho como mostrado abaixo.

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }
 7
Author: Dhaval Jardosh, 2017-10-16 15:53:24

1. Um cliente descarrega código javascript MyCode.JS de http://siteA-a origem.

O código que faz o download - a sua marca de script html ou xhr do javascript ou o que quer que seja - veio de, digamos, http://siteZ E, quando o navegador pede o meu código.js, ele envia uma origem: cabeçalho dizendo "origem: http://siteZ", porque pode ver que estás a pedir para siteA e siteZ !- siteA. (Você não pode parar ou interferir com presente.)

2. O cabeçalho de resposta do MyCode.js contém Access-Control-Allow-Origin: http://siteB , O Que eu pensei que significava que o meu código.a js foi autorizada a fazer referências cruzadas ao site B.

Não. Significa que só o siteB pode fazer este pedido. Então, o seu pedido para o meu código.js de siteZ recebe um erro em vez disso, e o navegador normalmente não lhe dá nada. Mas se você fizer o seu servidor retornar a-C-A-O: siteZ em vez disso, você vai ter MyCode.js . Ou se se enviar"*", vai funcionar, vai deixar toda a gente entrar. Ou se o servidor envia sempre o texto do cabeçalho origem:... mas... para segurança, se você tem medo de hackers, seu servidor só deve permitir origens em uma lista curta, que são autorizados a fazer esses pedidos. Então, Meu Código.o js vem de siteA. Quando ele faz pedidos para siteB, eles são todos de origem cruzada, o navegador envia origem: siteA, e siteB tem que tomar o siteA, reconhecer que está na lista curta de solicitantes autorizados, e enviar de volta a-c-a-O: siteA. Só então o navegador permitirá que o seu script obtenha o resultado desses pedidos.
 6
Author: OsamaBinLogin, 2016-02-27 01:37:43

Eu trabalho com o expresso 4 e o nó 7.4 e angular, eu tive o mesmo problema para ajudar isto:
a) lado do servidor: na aplicação file.eu dou cabeçalhos a todas as respostas como:

app.use(function(req, res, next) {  
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
 });  

Isto deve ter antes de todo o router.
Eu vi muitos cabeçalhos adicionados:

res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
Mas não preciso disso. b) lado do cliente: em enviar ajax você precisa adicionar: "witcredentials: true," como:
$http({
     method: 'POST',
     url: 'url, 
     withCredentials: true,
     data : {}
   }).then(function(response){
        // code  
   }, function (response) {
         // code 
   });
Boa sorte.
 5
Author: izik f, 2017-02-06 08:19:11
Sempre que começo a pensar no CORS, a minha intuição sobre qual local hospeda os cabeçalhos está incorrecta, tal como descreveu na sua pergunta. Para mim, ajuda pensar no propósito da mesma política de origem.

O objectivo da mesma política de origem é proteger-te de JavaScript malicioso em siteA.com aceder a informações privadas que escolheu partilhar apenas com siteB.com. sem a mesma política de origem, JavaScript escrito pelos autores de siteA.com poderia fazer o seu navegador fazer pedidos para siteB.com, usando os seus cookies de autenticação para siteB.com desta forma, siteA.com poderia roubar a informação secreta que você compartilha com siteA.com.

Às vezes você precisa de trabalhar no domínio cruzado, que é onde o CORS entra. O CORS relaxa a mesma política de origem para domainA.com, usando o cabeçalho Access-Control-Allow-Origin para listar outros domínios (domainB.com) que são confiáveis para executar JavaScript que pode interagir com domainA.com.

Para entender que Domínio deve servir os CORS headers, considere isto. Você visita malicious.com, que contém algum JavaScript que tenta fazer um pedido de cross domain para mybank.com. deve ser até mybank.com, não malicious.com, para decidir se define ou não headers CORS que relaxam a mesma política de origem, permitindo que o JavaScript de malicious.com para interagir com ele. Se fosse possível malicous.com para definir os seus próprios cabeçalhos de CORS, permitindo o seu próprio acesso JavaScript para mybank.com, isto anularia completamente a mesma origem politico.

Acho que a razão da minha má intuição é o ponto de vista que tenho ao desenvolver um site. Seuo meu site, com todoO Meu JavaScript, portanto não está a fazer nada malicioso e deve ser até me para especificar com que outros sites O Meu JavaScript pode interagir. Quando na verdade eu deveria estar pensando qual outros sites JavaScript estão tentando interagir com o meu site e devo usar o CORS para permitir?
 5
Author: Dom, 2018-01-28 18:47:01

Se estiver a usar o PHP, tente adicionar o seguinte código no desmame do ficheiro php:

Se está a utilizar localhost, tente isto:

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

Se está a usar domínios externos como o servidor, tente isto:

header("Access-Control-Allow-Origin: http://www.website.com");
 3
Author: Melvin Guerrero, 2017-01-18 15:30:06

Para a partilha de origem cruzada, definir o cabeçalho: 'Access-Control-Allow-Origin':'*';

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

Nó: app.use('Access-Control-Allow-Origin':'*');

Isto permitirá partilhar conteúdos para diferentes domínios.

 2
Author: user2923052, 2017-01-16 08:10:04

Em Python tenho usado o Flask-CORS biblioteca com grande sucesso. Faz com que lidar com o CORS seja super fácil e indolor. Adicionei alguns códigos da documentação da biblioteca abaixo.

A instalar:

$ pip install -U flask-cors

Um exemplo simples que permite aos CORS para todos os domínios em todas as rotas:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

Para exemplos mais específicos, consulte a documentação. Eu usei o exemplo simples acima para contornar a questão do CORS em uma aplicação iônica que estou construindo que tem que acessar um servidor de frasco separado.

 2
Author: agaidis, 2018-01-25 11:10:18