Я получаю эту ошибку, используя ngResource для вызова REST API в Amazon Web Services:

XMLHttpRequest не загружается http://server.apiurl.com: 8000 / с / логин? Login = facebook. Ответ на предполетный запрос не проходит проверку контроля доступа: Нет Заголовок Access-Control-Allow-Origin присутствует в запрошенном ресурс. Следовательно, к источнику 'http://localhost' доступ не разрешен. Ошибка 405

Сервис:

socialMarkt.factory('loginService', ['$resource', function ($resource) {
    var apiAddress = "http://server.apiurl.com:8000/s/login/";
    return $resource(apiAddress, {
        login: "facebook",
        access_token: "@access_token",
        facebook_id: "@facebook_id"
    }, {
        getUser: {
            method: 'POST'
        }
    });
}]);

Контроллер:

[...]
loginService.getUser(JSON.stringify(fbObj)),
    function (data) {
        console.log(data);
    },
    function (result) {
        console.error('Error', result.status);
    }
[...]

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

Ответы (24)

Вы столкнулись с проблемами CORS.

Есть несколько способов исправить / обойти это.

  1. Отключить CORS. Например: как отключить корс в хроме
  2. Используйте плагин для вашего браузера
  3. Используйте прокси, например nginx.пример настройки
  4. Выполните необходимые настройки для вашего сервера. Это больше зависит от веб-сервера, который вы загрузили в свой экземпляр EC2 (предполагая, что это то, что вы подразумеваете под «веб-службой Amazon»). Информацию о вашем конкретном сервере можно найти на веб-сайте enable CORS.

Точнее, вы пытаетесь получить доступ к api.serverurl.com с localhost. Это точное определение междоменного запроса.

• 100001 локальный хост, когда на самом деле у вас есть локальный сервер, который затем вызывает удаленный сервер.

, поэтому api.serverurl.com может стать localhost: 8000 / api, и ваш локальный nginx или другой прокси будет отправлять в правильное место назначения.


Теперь по многочисленным просьбам на 100% больше информации CORS.... такой же отличный вкус!


Обход CORS - это именно то, что показано тем, кто просто изучает интерфейс. https://codecraft.tv/courses/angular/http/http-with-promises/

Для сервера python flask вы можете использовать плагин flask-cors для включения междоменных запросов.

См .: https://flask-cors.readthedocs.io/en/latest/

JavaScript XMLHttpRequest и Fetch следуют политике одинакового происхождения. Так, веб-приложение, использующее XMLHttpRequest или Fetch, могло выполнять только HTTP запросы к собственному домену.

Источник: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Вы должны отправить HTTP-заголовок Access-Control-Allow-Origin: * со стороны вашего сервера.

Если вы используете Apache в качестве HTTP-сервера, вы можете добавить его в свой файл конфигурации Apache следующим образом:


    Header set Access-Control-Allow-Origin "*"

Mod_headers включен по умолчанию в Apache, однако вы можете убедиться, что он включен, запустив:

 a2enmod headers

То, что очень легко упустить ...

В проводнике решений щелкните правой кнопкой мыши api-project. В окне свойств установите для параметра «Анонимная аутентификация» значение Включено !!!

Если вы пишете chrome-extension

Вы должны добавить в manifest.json разрешения для вашего домена (ов).

"permissions": [
   "http://example.com/*",
   "https://example.com/*",
   "http://www.example.com/*",
   "https://www.example.com/*"
]

В PHP можно добавлять заголовки:

The standalone distributions of GeoServer include the Jetty application server. Enable Cross-Origin Resource Sharing (CORS) to allow JavaScript applications outside of your own domain to use GeoServer.

Uncomment the following and from webapps/geoserver/WEB-INF/web.xml:


  
      cross-origin
      org.eclipse.jetty.servlets.CrossOriginFilter
  
  
      cross-origin
      /*
  

Чтобы исправить проблемы с запросами из разных источников в приложении Node JS:

npm i cors

И просто добавьте строки ниже в app.js

let cors = require('cors')
app.use(cors())

There are some caveats when it comes to CORS. First, it does not allow wildcards * but don't hold me on this one I've read it somewhere and I can't find the article now.

If you are making requests from a different domain you need to add the allow origin headers.

 Access-Control-Allow-Origin: www.other.com 

If you are making requests that affect server resources like POST/PUT/PATCH, and if the mime type is different than the following application/x-www-form-urlencoded, multipart/form-data, or text/plain the browser will automatically make a pre-flight OPTIONS request to check with the server if it would allow it.

So your API/server needs to handle these OPTIONS requests accordingly, you need to respond with the appropriate access control headers and the http response status code needs to be 200.

The headers should be something like this, adjust them for your needs:

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

The max-age header is important, in my case, it wouldn't work without it, I guess the browser needs the info for how long the "access rights" are valid.

In addition, if you are making e.g. a POST request with application/json mime from a different domain you also need to add the previously mentioned allow origin header, so it would look like this:

   Access-Control-Allow-Origin: www.other.com 
   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

When the pre-flight succeeds and gets all the needed info your actual request will be made.

Generally speaking, whatever Access-Control headers are requested in the initial or pre-flight request, should be given in the response in order for it to work.

There is a good example in the MDN docs here on this link, and you should also check out this SO post

enter image description here

Используя опцию Cors в шлюзе API, я использовал следующие настройки, показанные выше

Также обратите внимание, что ваша функция должна возвращать HTTP-статус 200 в ответ на запрос OPTIONS, иначе CORS также не сработает.

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading of resources

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

In short - the webserver tells you (your browser) which sites you should trust for using that site.

  1. Scammysite.bad tries to tell your browser to send a request to good-api-site.good
  2. good-api-site.good tells your browser it should only trust other-good-site.good
  3. Your browser says that you really should not trust scammysite.bad's request to good-api-site.good and goes CORS saved you.

If you are creating a site, and you really don't care who integrates with you. Plow on. Set * in your ACL.

However if you are creating a site, and only site X, or even site X, Y and Z should be allowed, you use CORS to instruct the clients browser to only trust these sites to integrate with your site.

Browsers can of course choose to ignore this. Again, CORS protects your client - not you.

CORS allows * or one site defined. This can limit you, but you can get around this by adding some dynamic configuration to your web server - and help you being specific.

This is an example on how to configure CORS pr site is in Apache:

# Save the entire "Origin" header in Apache environment variable "AccessControlAllowOrigin"
# Expand the regex to match your desired "good" sites / sites you trust
SetEnvIfNoCase Origin "^https://(other-good-site\.good|one-more-good.site)$" AccessControlAllowOrigin=$0
# Assuming you server multiple sites, ensure you apply only to this specific site

    # Remove headers to ensure that they are explicitly set
    Header        unset Access-Control-Allow-Origin   env=AccessControlAllowOrigin
    Header        unset Access-Control-Allow-Methods  env=AccessControlAllowOrigin
    Header        unset Access-Control-Allow-Headers  env=AccessControlAllowOrigin
    Header        unset Access-Control-Expose-Headers env=AccessControlAllowOrigin
    # Add headers "always" to ensure that they are explicitly set
    # The value of the "Access-Control-Allow-Origin" header will be the contents saved in the "AccessControlAllowOrigin" environment variable
    Header always set Access-Control-Allow-Origin   %{AccessControlAllowOrigin}e     env=AccessControlAllowOrigin
    # Adapt the below to your use case
    Header always set Access-Control-Allow-Methods  "POST, GET, OPTIONS, PUT"        env=AccessControlAllowOrigin
    Header always set Access-Control-Allow-Headers  "X-Requested-With,Authorization" env=AccessControlAllowOrigin
    Header always set Access-Control-Expose-Headers "X-Requested-With,Authorization" env=AccessControlAllowOrigin

Очень распространенной причиной этой ошибки может быть то, что API хоста сопоставил запрос с методом http (например, PUT), а клиент API вызывает API, используя другой метод http (например, POST или GET)

В моем конфигурационном файле Apache VirtualHost я добавил следующие строки:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

Отключить безопасность Chrome. Создать ярлык Chrome щелкните правой кнопкой мыши -> свойства -> цель, вставьте этот "C: \ Program Files (x86) \ Google \ Chrome \ Application \ chrome.exe" --disable-web-security --user-data-dir = "c: / chromedev "

Для тех, кто использует Интегрированный прокси-сервер Lambda с API-шлюзом. Вам необходимо настроить лямбда-функцию так, как будто вы отправляете ей свои запросы напрямую, то есть функция должна правильно настраивать заголовки ответов. (Если вы используете пользовательские лямбда-функции, это будет обрабатываться API-шлюзом.)

//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
     //on success:
     callback(null, {
           statusCode: 200,
           headers: {
                "Access-Control-Allow-Origin" : "*"
           }
     }
}

Я столкнулся с этой проблемой, когда DNS-сервер был настроен на 8.8.8.8 (Google). На самом деле проблема была в маршрутизаторе, мое приложение пыталось подключиться к серверу через Google, а не локально (для моего конкретного случая). Я удалил 8.8.8.8, и это решило проблему. Я знаю, что эти проблемы решаются настройками CORS, но, возможно, у кого-то будут такие же проблемы, как у меня

Я использую AWS sdk для загрузки, потратив некоторое время на поиск в Интернете, я наткнулся на эту ветку. благодаря @lsimoneau 45581857 оказалось, что происходило то же самое. Я просто указал URL-адрес своего запроса на регион в моем ведре, добавив параметр региона, и он сработал.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });

Если вы случайно используете сервер IIS. вы можете установить ниже заголовки в опции заголовков HTTP-запроса.

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';

с этим все post, get и т. Д. Будут работать нормально.

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

  1. открытый (https://www.npmjs.com/package/cors#enabling-корс-предполетный)
  2. перейдите к установке и скопируйте команду npm install cors для установки через терминал узла
  3. перейдите к простому использованию (включить все запросы CORS) путем прокрутки. Затем скопируйте и вставьте полное объявление в ур-проекте и запустите его ... это наверняка сработает .. скопируйте код комментария и вставьте его в ur app.js или любой другой проект и попробуйте .. это сработает. это разблокирует каждый совместный доступ к ресурсам с перекрестным происхождением .. так что мы можем переключаться между серверами для вашего использования

Мой «API-сервер» - это приложение PHP, поэтому для решения этой проблемы я нашел следующее работающее решение:

Поместите строки в index.php

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

В веб-API AspNetCore эта проблема была устранена путем добавления Microsoft.AspNetCore.Cors (версия 1.1.1) и внесения следующих изменений в Startup.cs.

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddCors(options =>
    {
          options.AddPolicy("AllowAllHeaders",
                builder =>
            {
                    builder.AllowAnyOrigin()
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
    });
    .
    .
    .
}

и

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

и поместив [EnableCors ("AllowAllHeaders")] на контроллер.

Я думаю, что отключение CORS из Chrome - не лучший способ, потому что, если вы используете его в ionic, конечно, в Mobile Build проблема снова возникнет.

Так что лучше исправить в вашем Backend.

Прежде всего в заголовке нужно указать-

  • заголовок ('Access-Control-Allow-Origin: *');
  • header ('Header set Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"');

И если API ведет себя как GET и POST, то также установите в вашем заголовке -

if ($ _SERVER ['REQUEST_METHOD'] == 'OPTIONS') {if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header ("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) заголовок ("Access-Control-Allow-Headers:
{$ _SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']} "); exit (0);}

Наша команда иногда видит это, используя Vue, axios и C # WebApi. Добавление атрибута маршрута в конечную точку, которую вы пытаетесь достичь, исправляет это для нас.

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }

Для всех, кто использует HTTP API Api Gateway и прокси-маршрут ANY / {proxy +}

Для работы CORS вам необходимо явно определить методы маршрутизации.

enter image description here

Хотелось бы, чтобы это было более подробно описано в Документах AWS для настройки CORS для HTTP API

Был на двухчасовом звонке в службу поддержки AWS, и они зациклились на одном из своих старших разработчиков HTTP API, который дал эту рекомендацию.

Надеюсь, этот пост поможет сэкономить время и силы для тех, кто работает с Api Gateway HTTP API.

2022 WebDevInsider