Поле заголовка запроса Access-Control-Allow-Headers не разрешено Access-Control-Allow-Headers

224

Я пытаюсь отправить файлы на свой сервер с помощью почтового запроса, но при его отправке возникает ошибка:

Поле заголовка запроса Content-Type не разрешено Access-Control-Allow-Headers.

Итак, я погуглил ошибку и добавил заголовки:

$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"
}

Тогда я получаю ошибку:

Поле заголовка запроса Access-Control-Allow-Origin не разрешено Access-Control-Allow-Headers

Таким образом, я погуглил это, и единственный подобный вопрос, который я мог найти, был обеспечен половинным ответом тогда закрытым как не по теме. Какие заголовки я должен добавить / удалить?

user3194367
источник
Эти заголовки отправляются с сервера в браузер, поэтому браузер может решить, разрешено ли JS анализировать ответ. Добавление их в запрос не имеет значения.
Пельядольфо

Ответы:

189

Сервер (что запрос POST отправляется) должно включать в себя Access-Control-Allow-Headersзаголовок ( и т.д.) в своем ответе . Размещение их в вашем запросе от клиента не имеет никакого эффекта.

Это связано с тем, что сервер должен указать, что он принимает запросы разных источников (и что он разрешает Content-Typeзаголовок запроса и т. Д.) - клиент не может решить для себя, что данный сервер должен разрешать CORS.

Шай
источник
5
Как мне установить заголовки в бэкэнде?
user3194367
11
@ user3194367: Зависит от вашего бэкэнда.
Феликс Клинг,
15
Я думаю, мне придется поговорить с моим парнем на сервере.
user3194367
2
response.addHeader («Access-Control-Allow-Headers», «yourKey»);
Маюреш
2
@Mayuresh yourKey это что? Content-Type?
zhuguowei
240

У меня такая же проблема. В документации jQuery я нашел:

Для кросс-доменных запросов, задающих тип содержимого ничего, кроме application/x-www-form-urlencoded, multipart/form-dataили text/plainзапустит браузер для отправки предполетный OPTIONS - запрос на сервер.

Таким образом, хотя сервер разрешает перекрестный запрос источника, но не разрешает Access-Control-Allow-Headers, он будет выдавать ошибки. По умолчанию используется угловой тип контента application/json, который пытается отправить запрос OPTION. Попробуйте перезаписать угловой заголовок по умолчанию или разрешить Access-Control-Allow-Headersв конце сервера. Вот угловой образец:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});
рыболов
источник
28
Это должен быть принятый ответ, гораздо более информативный, чем другой!
Майк Шиндель
1
Я хотел бы получить multipart / form-data, потому что я хочу что-то выложить
Владо Панджич
3
or allow Access-Control-Allow-Headers in server endкак?
Омар
1
@ omar это зависит от того, какую серверную платформу вы используете. если в java есть пример для других ответов, если php, то есть имя функции headerдля установки заголовка ответа
Fisherman
1
Наконец, после двух дней исследований. У меня нет слов, чтобы поблагодарить вас!
Мики Салария
51

Если это кому-нибудь поможет (даже если это плохо, так как мы должны разрешить это только для целей разработки), вот решение Java, так как я столкнулся с той же проблемой. [Редактировать] Не используйте подстановочный знак *, так как это плохое решение, используйте, localhostесли вам действительно нужно, чтобы что-то работало локально.

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
источник
Как свидетельствуют многочисленные ответы для Access-Control-Request-Headers, есть четкие различия из-за разных сред. То, что работало для меня, было получить доступ к объекту запроса и вывести значения для заголовков, но в частности значение заголовка для «Access-Control-Request-Headers». Затем скопируйте / вставьте это в ваш response.setHeader («Access-Control-Allow-Headers», «{paste here}»); Я также использую Java, но мне потребовались дополнительные значения, а некоторые из упомянутых в этом ответе мне не нужны.
Пророки программного обеспечения
Это было частичное (и, как уже говорилось, плохое) решение, чтобы помочь людям и поделиться подсказками год назад. Я не вижу смысла в голосовании вниз, но это ваша свобода. Идея состоит в том, чтобы разрешить заголовки на стороне сервера, чтобы при публикации запроса OPTION клиент / браузер знал, какие заголовки разрешены. Я признаю, что есть некоторая путаница, мой фильтр CORS сильно изменился с тех пор. В качестве лучшей практики Access-Control-Allow-Origin никогда не должен быть *; в моей реализации это устанавливается свойством.
lekant
Решение было отредактировано, чтобы включить лучшие практики
lekant
16

Сервер (которому отправляется запрос POST) должен включить заголовок Content-Type в свой ответ.

Вот список типичных заголовков для включения, включая один пользовательский заголовок «X_ACCESS_TOKEN»:

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

Вот что должен настроить ваш http-сервер для веб-сервера, на который вы отправляете свои запросы.

Вы также можете попросить вашего сервера выставить заголовок «Content-Length».

Он распознает это как запрос общего доступа к ресурсам (CORS) и должен понимать последствия создания этих конфигураций сервера.

Подробнее см .:

L3x
источник
13

Вы можете активировать правильный заголовок в PHP с помощью этого:

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");
Винод Дхакад
источник
4
Пожалуйста, опишите, чем ваш ответ отличается от других ответов. Просто размещение некоторого кода не очень полезно.
августа
1
Вы рок-звезда, остальные ответы вникают в техническую сторону. Ваша решает мою проблему, указывая методы, которые также должны быть разрешены!
Даниэль З.А.
1
@DanielZA, хотя я понимаю, что вы подразумеваете под «другими ответами, углубляющимися в техническую сторону», поскольку вы просто хотите, чтобы ваш код выполнялся, SO предназначен для углубления в техническую сторону вещей, так как вы должны знать, почему все работает, а не только как заставить потом работать. Не кодируйте это поведение, комментируя решения ...
nicolasassi
8

У меня работает 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();
});
Фернандо Габриэли
источник
имеет значение порядок Access-Control-Allow-Methods?
вини
@ Vini, я думаю, это не имеет значения.
Кодирование ниндзя
4

Заголовки, которые вы пытаетесь установить, являются заголовками ответа . Они должны быть предоставлены в ответе сервером, к которому вы обращаетесь.

Им не место на клиенте. Было бы бессмысленно иметь средства для предоставления разрешений, если бы они могли быть предоставлены сайтом, который запрашивал разрешение, а не сайтом, которому принадлежали данные.

Quentin
источник
Как мне установить заголовки в бэкэнде?
user3194367
@ user3194367 - Это зависит от вашего бэкэнда. Я не знаю, какой HTTP-сервер или язык программирования вы делаете запрос.
Квентин
Я думаю, мне придется поговорить с моим парнем на сервере.
user3194367
3

Если кто-то испытывает эту проблему с экспресс-сервером, добавьте следующее промежуточное ПО

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
realappie
источник
3

Если вы тестируете некоторые запросы javascript для ionic2 или angularjs 2 в chrome на ПК или Mac, убедитесь, что вы установили плагин CORS для браузера chrome, чтобы разрешить перекрестное происхождение.

запросы на получение майбы будут работать без этого, но для отправки, размещения и удаления потребуется установить плагин cors, чтобы тестирование прошло без проблем, что определенно не круто, но я не знаю, как люди делают это без плагина CORS.

а также убедитесь, что ответ JSON не возвращается 400 по состоянию JSON

albaiti
источник
3

это проблема бэкэнда. если вы используете sails api, измените cors.js и добавьте сюда свой файл

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'
};
Седат Y
источник
3

В Asp Net Core , чтобы быстро заставить его работать на развитие; в Startup.cs, Configure methodдобавить

app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Габриэль П.
источник
2

В моем случае я получаю несколько параметров как @HeaderParam в метод веб-службы.

Эти параметры ДОЛЖНЫ быть объявлены в вашем фильтре CORS следующим образом:

@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
источник
2

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headersошибка означает, что Access-Control-Allow-Originполе заголовка HTTP не обработано или не разрешено ответом. Удалить Access-Control-Allow-Originполе из заголовка запроса.

Тони Старк
источник
2

Если вы используете localhostPHP и установите это для решения проблемы:

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

С вашего внешнего использования:

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

и бум больше никаких проблем localhost!

jerryurenaa
источник