Campo de cabeçalho de solicitação Acesso-Controle-Permitir-Cabeçalhos não é permitido por Acesso-Controle-Permitir-Cabeçalhos

224

Estou tentando enviar arquivos para o meu servidor com uma solicitação de postagem, mas quando ele envia causa o erro:

O campo de cabeçalho da solicitação Content-Type não é permitido pelo Access-Control-Allow-Headers.

Então pesquisei o erro no Google e adicionei os cabeçalhos:

$http.post($rootScope.URL, {params: arguments}, {headers: {
    "Access-Control-Allow-Origin" : "*",
    "Access-Control-Allow-Methods" : "GET,POST,PUT,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}

Então eu recebo o erro:

O campo de cabeçalho da solicitação Access-Control-Allow-Origin não é permitido pelos Access-Control-Allow-Headers

Então, pesquisei isso no Google e a única pergunta semelhante que pude encontrar foi fornecida meia resposta e encerrada como fora de tópico. Quais cabeçalhos devo adicionar / remover?

user3194367
fonte
Esses cabeçalhos são enviados do servidor para o navegador para que o navegador possa decidir se o JS pode analisar a resposta. Adicioná-los à solicitação não tem valor.
Pellyadolfo

Respostas:

189

O servidor (para o qual a solicitação POST é enviada) precisa incluir o Access-Control-Allow-Headerscabeçalho (etc) em sua resposta . Colocá-los em sua solicitação do cliente não tem efeito.

Isso ocorre porque cabe ao servidor especificar que aceita solicitações de origem cruzada (e que permite o Content-Typecabeçalho da solicitação, etc.) - o cliente não pode decidir por si mesmo que um determinado servidor deve permitir o CORS.

Shai
fonte
5
Como faço para definir os cabeçalhos no back-end?
User3194367
11
@ user3194367: Depende do seu back-end.
Felix Kling
15
Acho que vou ter que falar com o meu servidor.
User3194367
2
response.addHeader ("Controle de acesso-permitir-cabeçalhos", "suaKey");
21416 Mayuresh
2
@Mayuresh yourKey é o que? Content-Type?
zhuguowei 13/09/16
240

Eu tive o mesmo problema. Na documentação do jQuery, encontrei:

Para solicitações de domínio cruzado, definindo o tipo de conteúdo a qualquer coisa que não seja application/x-www-form-urlencoded, multipart/form-dataou text/plainirá acionar o navegador para enviar uma opções de pré-impressão solicitar ao servidor.

Portanto, embora o servidor permita solicitações de origem cruzada, mas não permita Access-Control-Allow-Headers, lançará erros. Por padrão, o tipo de conteúdo angular é application/json, que está tentando enviar uma solicitação OPTION. Tente substituir o cabeçalho padrão angular ou permitir Access-Control-Allow-Headersno final do servidor. Aqui está uma amostra angular:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});
Pescador
fonte
28
Esta deve ser uma resposta aceita, muito mais informativa que a outra!
Mike Szyndel 24/03
1
Gostaria multipart / form-data, porque eu quero uplaod algo
Vlado Pandžić
3
or allow Access-Control-Allow-Headers in server endcomo?
Omar
1
@omar depende de qual plataforma de servidor você está usando. Se o Java não é exemplo em outras respostas, se php então há um nome de função headerpara conjunto de cabeçalho da resposta
Fisherman
1
Finalmente, após dois dias de pesquisa. Não tenho palavras para agradecer!
Mekey Salaria
51

Se isso ajudar alguém, (mesmo que seja um pouco ruim, pois devemos apenas permitir isso para fins de desenvolvedor), aqui está uma solução Java, pois encontrei o mesmo problema. [Editar] Não use o curinga *, pois é uma péssima solução, use localhostse você realmente precisar de algo trabalhando localmente.

public class SimpleCORSFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "my-authorized-proxy-or-domain");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

}
lekant
fonte
Como testemunhado por várias respostas para cabeçalhos de solicitação de controle de acesso, há claramente diferenças devido a diferentes ambientes. O que funcionou para mim foi obter acesso ao objeto de solicitação e despejar os valores para os cabeçalhos, mas especificamente o valor do cabeçalho para "Access-Control-Request-Headers". Em seguida, copie / cole isso em sua response.setHeader ("Access-Control-Allow-Headers", "{paste here}"); Também estou usando Java, mas exigi valores adicionais e alguns mencionados nesta resposta não eram necessários.
Software Profetas
Essa foi uma solução parcial (e, como já foi dito, ruim) para ajudar as pessoas e compartilhar pistas um ano atrás. Eu não vejo o ponto de votar, mas esta é a sua liberdade. A idéia é permitir os cabeçalhos no lado do servidor para que, quando uma solicitação de OPÇÃO for publicada, o cliente / navegador saiba quais cabeçalhos são permitidos. Reconheço que há um pouco de confusão, meu filtro CORS mudou muito desde então. Como prática recomendada, o Access-Control-Allow-Origin nunca deve ser *; na minha implementação, é definido por uma propriedade.
lekant
A solução foi editada para incluir as práticas recomendadas
lekant
16

O servidor (para o qual a solicitação POST é enviada) precisa incluir o cabeçalho Content-Type em sua resposta.

Aqui está uma lista de cabeçalhos típicos a serem incluídos, incluindo um cabeçalho "X_ACCESS_TOKEN" personalizado:

"X-ACCESS_TOKEN", "Access-Control-Allow-Origin", "Authorization", "Origin", "x-requested-with", "Content-Type", "Content-Range", "Content-Disposition", "Content-Description"

É para isso que o pessoal do servidor http precisa configurar para o servidor da Web para o qual você está enviando suas solicitações.

Você também pode solicitar ao seu servidor que exponha o cabeçalho "Comprimento do conteúdo".

Ele reconhecerá isso como uma solicitação de compartilhamento de recursos de origem cruzada (CORS) e deve entender as implicações de fazer essas configurações de servidor.

Para detalhes, consulte:

l3x
fonte
13

Você pode ativar o cabeçalho apropriado no PHP com isso:

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");
Vinod Dhakad
fonte
4
Descreva como sua resposta é diferente das outras respostas. Postar um código não é muito útil.
oscfri
1
Você é uma estrela do rock, o restante das respostas investiga o lado técnico. Seu resolve o meu problema, especificando os métodos que também devem ser permitidos!
Daniel ZA
1
@ DanielZA, embora eu entenda o que você quer dizer com "as outras respostas se aprofundam no lado técnico", como você só quer que seu código seja executado, o SO deve se aprofundar no lado técnico das coisas, pois você deve saber por que as coisas não estão funcionando apenas como fazer então funcionar. Não encorage este comportamento ao comentar sobre soluções ...
nicolasassi
8

O seguinte funciona para mim com o nodejs:

xServer.use(function(req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", 'http://localhost:8080');
  res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Accept');

  next();
});
Fernando Gabrieli
fonte
a ordem dos métodos de controle de acesso e permissão é importante?
vini
@ Vini, acho que não importa.
Ninja Coding
4

Os cabeçalhos que você está tentando definir são cabeçalhos de resposta . Eles devem ser fornecidos, na resposta, pelo servidor para o qual você está fazendo a solicitação.

Eles não têm lugar definido no cliente. Seria inútil ter um meio de conceder permissões se elas pudessem ser concedidas pelo site que desejava permissão em vez do site que possuía os dados.

Quentin
fonte
Como faço para definir os cabeçalhos no back-end?
User3194367
@ user3194367 - Depende do seu back-end. Não sei para qual servidor HTTP ou linguagem de programação você está fazendo a solicitação.
Quentin
Acho que vou ter que falar com o meu servidor.
User3194367
3

Se alguém tiver esse problema com um servidor expresso, adicione o seguinte middleware

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

se você estiver testando algumas solicitações javascript para ionic2 ou angularjs 2, no chrome no pc ou mac, certifique-se de instalar o plugin CORS no navegador chrome para permitir a origem cruzada.

O mayba get request funcionará sem a necessidade disso, mas postar e colocar e excluir precisará instalar o plugin cors para testes sem problemas, isso definitivamente não é legal, mas eu não sei como as pessoas fazem isso sem o plugin CORS.

e também verifique se a resposta json não está retornando 400 por algum status json

albaiti
fonte
3

este é um problema de back-end. se usar velas api no backend mudar cors.js e adicione seu arquivado aqui

module.exports.cors = {
  allRoutes: true,
  origin: '*',
  credentials: true,
  methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
  headers: 'Origin, X-Requested-With, Content-Type, Accept, Engaged-Auth-Token'
};
Sedat Y
fonte
3

No Asp Net Core , para fazê-lo funcionar rapidamente para o desenvolvimento; em Startup.cs, Configure methodadd

app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Gabriel P.
fonte
2

No meu caso, estou recebendo vários parâmetros como @HeaderParam em um método de serviço da web.

Esses parâmetros DEVEM ser declarados no seu filtro CORS dessa maneira:

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        ...
        headers.add("Access-Control-Allow-Headers", 
        /*
         * name of the @HeaderParam("name") must be declared here (raw String):
         */
        "name", ...);
        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");   
    }
}
russellhoff
fonte
2

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headerserror significa que o Access-Control-Allow-Origincampo do cabeçalho HTTP não é tratado ou permitido por resposta. Remova o Access-Control-Allow-Origincampo do cabeçalho da solicitação.

Tony Stark
fonte
2

Se você estiver usando um localhostPHP configurado para resolver o problema:

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

No seu uso front-end:

{headers: {"Content-Type": "application/json"}}

e boom sem mais problemas localhost!

jerryurenaa
fonte