A origem <origem> não é permitida pelo Access-Control-Allow-Origin

184
XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

Li sobre solicitações de ajax entre domínios e entendi o problema de segurança subjacente. No meu caso, 2 servidores estão sendo executados localmente e gostam de ativar solicitações entre domínios durante o teste.

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

Estou emitindo uma solicitação ajax para localhost:8080 - GAE serverenquanto minha página é carregada do servidor de nós. Qual é o mais fácil e seguro (não deseja iniciar o Chrome com a disable-web-securityopção). Se eu precisar alterar 'Content-Type', devo fazê-lo no servidor do nó? Quão?

bsr
fonte
Uma solução mais rápida pode ser encontrada aqui: stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

Respostas:

195

Como eles estão sendo executados em portas diferentes, eles são diferentes em JavaScript origin. Não importa se eles estão na mesma máquina / nome do host.

Você precisa ativar o CORS no servidor (localhost: 8080). Confira este site: http://enable-cors.org/

Tudo o que você precisa fazer é adicionar um cabeçalho HTTP ao servidor:

Access-Control-Allow-Origin: http://localhost:3000

Ou, para simplificar:

Access-Control-Allow-Origin: *

Não use "*" se o seu servidor estiver tentando definir um cookie e você usar withCredentials = true

ao responder a uma solicitação credenciada, o servidor deve especificar um domínio e não pode usar curingas.

Você pode ler mais sobre withCredentialsaqui

Foguete Hazmat
fonte
se quisermos adicionar esse cabeçalho em um HTML, o que devemos fazer?
Azam Alvi
1
Não achei que a porta fosse necessária, mas se você estiver usando uma porta não padrão como 3000, precisará incluí-la na política do CORS.
Michael Connor
4
Obrigado por esta resposta. Só quero destacar as implicações de segurança do uso de '*' como o valor aqui. Isso permite todas as origens: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… Parece que o primeiro exemplo seria o melhor em termos de menor acesso. Detalhes sobre como fazer isso com vários domínios aqui: stackoverflow.com/a/1850482/1566623 #
Christopher Kuttruff
14
Por uma questão de clareza, quando se diz que você precisa "adicionar um cabeçalho HTTP ao servidor", isso significa que o Access-Control-Allow-Origincabeçalho fornecido precisa ser um cabeçalho adicionado às respostas HTTP que o servidor envia. Esse cabeçalho precisa fazer parte da resposta do servidor, não precisa fazer parte da solicitação do cliente . Especificamente, o que acontece é antes que o cliente faça a solicitação real desejada, o navegador envia uma OPTIONSsolicitação antes e, se a resposta do servidor a essa OPTIONSsolicitação não contiver o cabeçalho, o navegador não enviará a solicitação desejada.
AjaxLeung
1
É importante ler as dicas relevantes para seus servidores de back-end em enable-cors.org.
Karlth 3/01/19
69

Se você precisar de uma solução rápida no Chrome para solicitações de ajax, esse plug-in do Chrome permitirá automaticamente acessar qualquer site de qualquer origem, adicionando o cabeçalho de resposta adequado

Extensão do Chrome Allow-Control-Allow-Origin: *

Billy Baker
fonte
6
Não sei por que você não está recebendo mais votos. Isso é o menos invasivo para o desenvolvimento no host local com o Chrome.
David Betz
definitivamente concordo. Fácil de ativar para o localhost dev em um servidor remoto sem precisar alterar a configuração do servidor remoto.
Jens Wegar #
@DavidBetz: considerando que você verificar a extensão e confiar nele, é claro;)
haylem
2
ESTA DEVE SER A RESPOSTA SUPERIOR! Especialmente onde localhost está em causa.
Benedict
16
Se essa fosse uma boa solução, o CORS não teria sido inventado em primeiro lugar. A aplicação desse cabeçalho a qualquer host desativa a proteção CORS e expõe você a scripts maliciosos, não apenas aos seus. Não se surpreenda se sua conta bancária estiver subitamente vazia.
anta
54

Você precisa habilitar o CORS para resolver isso

se seu aplicativo for criado com o node.js simples

defini-lo em seus cabeçalhos de resposta como

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

se seu aplicativo for criado com estrutura expressa

use um middleware CORS como

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

e aplicar via

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

Aqui estão dois links de referência

  1. como permitir-cors-em-express-nodejs
  2. diving-into-node-js-very-first-app # veja a seção Ajax
mithunsatheesh
fonte
você pode especificar como usar config.allowedDomains. diga no meu caso que uri devo colocar lá?
BSR
@bsr: você pode usar *ou specific domaindeseja acessar.
Mithunsatheesh
1
então eu sou o único recebendo app.configure()não é um erro de função?
Pramesh Bajracharya
@PrameshBajrachaya Não incluí a parte "app.configure" - somente "app.use (allowCrossDomain)" e funcionou para mim.
Giorgos Sfikas
8

Aceito a resposta do @Rocket hazmat, pois me leva à solução. De fato, estava no servidor GAE que eu precisava definir o cabeçalho. Eu tive que definir isso

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

configuração "Access-Control-Allow-Origin" deu apenas erro

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

Além disso, se o token de autenticação precisar ser enviado, adicione-o também

"Access-Control-Allow-Credentials" -> "true"

Além disso, no cliente, defina withCredentials

isso faz com que 2 solicitações sejam enviadas ao servidor, uma com OPTIONS. O cookie de autenticação não é enviado com ele, portanto, é necessário tratar a autenticação externa.

bsr
fonte
7

No router.js, basta adicionar código antes de chamar os métodos get / post. Funciona para mim sem erros.

//Importing modules @Brahmmeswar
const express = require('express');
const router = express.Router();

const Contact = require('../models/contacts');

router.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });
Brahmmeswara Rao Palepu
fonte
5

Eu estava enfrentando um problema ao chamar recurso de origem cruzada usando ajax do chrome.

Eu usei o nó js e o servidor http local para implantar meu aplicativo js do nó.

Eu estava recebendo resposta de erro ao acessar o recurso de origem cruzada

Eu encontrei uma solução nisso,

1) Adicionei o código abaixo ao meu arquivo app.js

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");

2) Na minha página html chamada recurso de origem cruzada usando $.getJSON();

$.getJSON("http://localhost:3000/users", function (data) {
    alert("*******Success*********");
    var response=JSON.stringify(data);
    alert("success="+response);
    document.getElementById("employeeDetails").value=response;
});
Chaitanya
fonte
5

Se você estiver usando express, poderá usar o cors middleware da seguinte maneira:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())
Akalanka Weerasooriya
fonte
3

Adicione isso ao servidor NodeJS abaixo das importações:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
Ryan Cocuzzo
fonte
3

Se você obteve 403 depois disso, reduza os filtros na configuração do tomcat WEB.XML para o seguinte:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
</filter>
Farbod Aprin
fonte
2

Finalmente consegui a resposta para o apache Tomcat8

Você precisa editar o arquivo tomcat web.xml.

provavelmente estará dentro da pasta webapps,

sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml

encontre e edite

<web-app>


<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



</web-app>

Isso permitirá que Access-Control-Allow-Origin todos os hosts. Se você precisar alterá-lo de todos os hosts para apenas seu host, poderá editar o

<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>

acima do código * para o seu http: // your_public_IP ou http://www.example.com

você pode consultar aqui a documentação do filtro Tomcat

obrigado

Shinto Joseph
fonte
1

Oi Esta é a maneira de resolver o problema do CORS no nó Basta adicionar essas linhas no lado "api" do servidor no Node.js (ou qualquer que seja o arquivo do servidor), antes de instalar o "cors"

    const express = require('express');
    const app = express();
    app.use(express.json());
    var cors = require('cors');
    app.use(cors());
Saad Abbasi
fonte
0

use dataType: 'jsonp', funciona para mim.

   async function get_ajax_data(){

       var _reprojected_lat_lng = await $.ajax({

                                type: 'GET',

                                dataType: 'jsonp',

                                data: {},

                                url: _reprojection_url,

                                error: function (jqXHR, textStatus, errorThrown) {

                                    console.log(jqXHR)

                                },

                                success: function (data) {

                                    console.log(data);



                                    // note: data is already json type, you just specify dataType: jsonp

                                    return data;

                                }

                            });





 } // function               
hoogw
fonte
0

Para PHP, use isso para definir cabeçalhos.

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
Hamza Waleed
fonte
0
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "*");
next();});

adicione isso às suas rotas para as quais você está chamando no front-end. Por exemplo, se você chamar http: // localhost: 3000 / users / register, deverá adicionar este fragmento de código ao arquivo .js de back-end que esta rota estabelece.

Sujeewa K. Abeysinghe
fonte
0

Caso alguém procure a solução, se você estiver usando express aqui, é a solução rápida.

const express = require('express')
const cors = require('cors')
const app = express()

1) instale cors usando o npm npm install cors --save

2) importá-lo [requerer] const cors = require('cors')

3) use-o como middleware app.use(cors())

para mais detalhes e uso de cors . É isso, espero que funcione.

Badri Paudel
fonte