Angular2-ответ на предварительный запрос не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin»

Я вызываю http-сообщение в Angular 2. Это отлично работает в почтовом человеке, но когда я реализую этот вызов API в Angular 2, я получаю сообщение «Нет ошибки «Access-Control-Allow». Вот мой код

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            headers.append('Access-Control-Allow-Origin','*');
            let options = new RequestOptions({ headers: headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,options)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

Или я могу это сделать? Просто передайте заголовок вместо параметров

getInspections(): Observable<IInspection[]> {
        if (!this.inspections) {
            let body =JSON.stringify({"Statuses":["Submitted", "Opened"]});
            let headers = new Headers({ 'Content-Type': 'application/json' });

            //headers.append('Access-Control-Allow-Origin','*');
          //  let options = new RequestOptions({ headers:headers });

            return this.http.post(this._baseUrl + '/api/Inspect/ListI',body,headers)
                .map((res: Response) => {
                    this.inspections = res.json();
                    return this.inspections;
                })
                .catch(this.handleError);
        }
        else {
            //return cached data
            return this.createObservable(this.inspections);
        }
    }

person raj kumar    schedule 17.08.2016    source источник
comment
Вы можете передавать заголовки напрямую (я думаю, это должен быть объект типа {headers} (хотя и не уверен), но это вообще не связано с вашей ошибкой CORS.   -  person Günter Zöchbauer    schedule 17.08.2016


Ответы (2)


Заголовки CORS, такие как

headers.append('Access-Control-Allow-Origin','*');

должны быть предоставлены сервером. Добавлять их на клиенте бессмысленно.

person Günter Zöchbauer    schedule 17.08.2016
comment
я использую сторонний API, так как я могу добавить туда заголовки - person sainanky; 08.01.2018
comment
Вероятно, это означает, что владелец не хочет, чтобы xou использовал API таким образом. Вы можете обойти это, ретранслируя запросы через сервер, которым вы управляете. CORS актуален только для запросов, сделанных из браузера, а не с сервера. - person Günter Zöchbauer; 08.01.2018

При использовании нестандартных заголовков (по-видимому, json считается нестандартным) выполняется предварительная проверка, чтобы узнать, можно ли выполнить запрошенное действие (в данном случае «опубликовать»). Только сервер может ответить разрешительными заголовками. То, как вы отвечаете, зависит от языка вашего сервера. В моем webapi2 я реализую cors в WebAppConfig

 var cors = new EnableCorsAttribute("http://localhost:3000", "*", "GET, HEAD, OPTIONS, POST, PUT");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

Обратите внимание, что для живого сервера вы должны заменить ссылку localhost на настроенный веб-список (или конкретное место, где находится вызывающий абонент). SupportsCredentials необходимы только в том случае, если вы используете аутентификацию.

Для обработки предварительной проверки я добавил в Globals.asax метод, который просто перехватывает предварительные сообщения и возвращает достаточно данных для продвижения публикации.

protected void Application_BeginRequest()
    {
        if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
        {
            var origin = HttpContext.Current.Request.Headers["Origin"];

            Response.Headers.Add("Access-Control-Allow-Origin", origin);
            Response.Headers.Add("Access-Control-Allow-Headers", "content-type, withcredentials, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST, PUT");

            Response.Flush();
        }
    }

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

Имейте в виду, что есть некоторые читы разработчиков. - Если вы запускаете Internet Explorer на локальном хосте (для целей разработки), то ie игнорирует порт, который не делает большинство других браузеров, что упрощает задачу. Существует также расширение CORS для Chrome, которое добавляет заголовки для вас. Наконец, вы увидите много кода, который использует возврат '*' (чтобы разрешить все) - во что бы то ни стало используйте их, чтобы заставить код работать, но перед выпуском заблокируйте их гораздо более агрессивно.

person Matrim    schedule 18.08.2016
comment
Я не совсем понимаю вас, когда вы говорите Only the server can respond with the permissive headers. А позже There is also a CORS enhancement for Chrome which adds the headers for you. Chrome на стороне клиента, нет? - person fralbo; 25.07.2018
comment
рекомендовал бы вам изучить, что делает расширение Chrome CORS, которое должно прояснить вашу путаницу. Это усовершенствование может решить ограниченную проблему в среде разработки. Полный ответ нужен для производства. - person Matrim; 30.07.2018