Нормальный запрос
Недавно другие должны вызвать функцию нашей системы, а другая сторона надеется предоставить API, чтобы он мог обновить данные. Поскольку этот одноклассник является разработчиком клиента, у него есть код, аналогичный следующему.
@Requestmapping (method = requestMethod.post, value = "/update.json", products = mediaType.application_json_value) public @responsebody contacter == 123) {contacterro.setusername ("adminupdate-wangdachui");} return contacterro;}Клиент инициирует HTTP -запрос через код, чтобы вызвать его. Затем студент спросил: он надеялся использовать вызовы JS через браузер, так что была проблема между доменом.
Почему кросс-домен
Проще говоря, браузер ограничивает доступ к коду JS в соответствии с сайтом A, чтобы сделать запрос Ajax на URL -адрес в соответствии с сайтом B. Если текущее доменное имя является www.abc.com, то код JS, работающий в текущей среде, не может получить доступ к ресурсам в соответствии с доменным именем www.zzz.com по соображениям безопасности.
Например: следующий код можно использовать для нормального вызова интерфейса через код JS под этим доменным именем
(function () {var url = "http: // localhost: 8080/api/home/update.json"; var data = {"userid": 123, "username": "wangdachui"}; $. Ajax ({url: url, тип: 'post', datatype: 'Json', data: $. Application/json '}). Dod (function (result) {console.log ("success"); console.log (result);}). Fail (function () {console.log ("error");})}) () ()Вывод:
Object {userId: 123, имя пользователя: "AdminupDate-Wangdachui"}Однако доступ к другим доменным именам вызовет ошибку:
Параметры http: // localhost: 8080/api/home/update.jsonxmlhttprequest не может загрузить http: // localhost: 8080/api/home/update.json. Ответ на запрос на предварительный полевой пропуск не проходит проверку управления доступом: Направный ресурс не присутствует. Происхождение 'null' поэтому не допускается доступа. Ответ имел код состояния HTTP 403.
Решение
Jsonp
Использование JSONP для перекрестного домена является относительно распространенным явлением, но когда был написан интерфейс, как сервер, так и сторона вызова должны быть преобразованы и совместимы с исходным интерфейсом, что слишком много работы, поэтому мы рассматриваем другие методы.
Протокол CORS
Согласно ссылкам: каждая страница должна вернуть HTTP-заголовок с именем «Access-Control-Allow-Origin», чтобы разрешить доступ к сайту в иностранном домене. Вы можете просто раскрыть ограниченные ресурсы и ограниченный доступ вне домена. В режиме COR ответственность за управление доступом может быть помещена в руки разработчика страницы, а не администратора сервера. Конечно, разработчики страниц должны написать специальный код обработки, чтобы разрешить доступ к внешнему миру. Мы можем понять это как: если запрос должен разрешить доступ к междомену, вам необходимо установить иоригин-контроль доступа в заголовке HTTP, чтобы решить, какие сайты разрешать доступа. Если вам нужно разрешить запросы с www.foo.com на кросс-домен, вы можете установить: Access-control-allow-origin: http://www.foo.com. Или доступ к доступу-светоку: *. CORS поддерживается в большинстве современных браузеров в рамках HTML5.
У Cors есть следующие общие заголовки
Access-Control-Allow-Origin: http: //foo.orgaccess-control-max-age: 3628800access-control-allow-methods: get, put, deleteaccess-control-llow-headers: content-type control- Allow- Allow-demon-ale-ine. запросы «Access-Control-Max-Age» указывает, что в течение 3628800 секунд не требуется запросы на предварительную проверку. Результат «Доступ-контроль-методы» указывает на то, что он позволяет получить, удалять, удалять запросы на домену «заголовки-контроль доступа» указывает на то, что он позволяет перекрестным запросам включать заголовки типа контента
Основной процесс CORS
Во -первых, выдается запрос на предварительный полевой полет, который сначала выпускает метод опций и запрос, содержащий заголовок «Происхождение» на сервер ресурсов. Этот ответ может контролировать метод запроса COR, заголовок HTTP и информацию о проверке. Реальный запрос на иностранную домену будет инициирован только после разрешения запроса.
Spring MVC поддерживает CORS
Ответ на запрос на предварительный полевой пропуск не проходит проверку управления доступом: Направный ресурс не присутствует. Происхождение 'null' поэтому не допускается доступа. Ответ имел код состояния HTTP 403.
Из приведенного выше сообщения об ошибке мы видим, что прямая причина заключается в том, что в заголовке запроса нет заголовка-образного торигина. Таким образом, наша прямая идея - добавить этот заголовок в заголовок запроса. Сервер может вернуть 403, указывая, что сервер действительно обработал запрос.
MVC Interceptor
Во -первых, мы настраиваем перехватчик, чтобы перехватить запрос и регистрировать информацию о заголовке запроса.
Debug RequestUrl: /api/home/update.json Метод отладки: Опции Отладка Заголовок Хост: Localhost: 8080 Подключение заголовка отладчика: Hept-Alive. AppleWebkit/537.36 (khtml, как гекко) Chrome/49.0.2623.87 Safari/537.36 Header Header Header-Control-Request Headers: Принять, заголовок отладки контента. Принятие языка: ZH-CN, ZH; Q = 0,8, EN; Q = 0,6
Печать журнала в Posthandle обнаружила, что статус ответа в настоящее время составляет 403. Отслеживание кодов SpringMVC обнаружило, что в org.springframework.web.servlet.dispatcherservlet.dodispatch, HandlerexecutionChain будет получена на основе запроса. После того, как SpringMVC приобретает обычный процессор, он проверит, является ли это перекрестным запросом. Если это так, это заменит исходный экземпляр.
@OverridePublic final HandleRexeCutionChain Gethandler (httpservletrequest) Throws Exception {Object Handler = gethandlerinternal (запрос); if (Handler == null) {handler = getDefaulthandler ();} if (handler == null) {return null;} /// bean name или resolvolof? handlername = (string) handler; handler = getApplicationContext (). getBean (handlername);} handleRexecutionChain executionChain = gethandlerexecutionChain (Handler, запрос); if (corsutils.iscorsrequest (request)) {corsconfiguration globalconfig = this.corsconfigsource.getCorsConfiguration (запрос); corsConfiguration handlerconfig = getCorsConfiguration (Handler, запрос); corsConfiguration config = (GlobalConfig! = null? GlobalConfig.combine (handlerconfig): handlerconfig); FeeforcutionChinate (HandlerChineain (Handlerconfigchain (executionHectionHain (HandlerChaineain (Handlerconfighain (HandlerceChineAine); config);} return executionChain;}Метод проверки также очень прост, то есть проверить, есть ли в заголовке запроса поле происхождения.
Public Static Boolean IscorsRequest (httpservletrequest) {return (request.getheader (httpheaders.origin)! = null);}Затем запрос будет передан HttprequestHandlerAdapter.handle для обработки, и различная логика будет обрабатываться в соответствии с ручкой. Предыдущее решение основано на заголовке запроса в качестве перекрестного запроса. Полученным обработчиком является префлгхандлер, который реализован как:
@OverridePublic void handleRequest (httpservletrequest, httpservletresponse response) throws ioexception {corsprocessor.processrequest (this.config, запрос, ответ);}Продолжать следить за
@OverridePublic Boolean ProcessRequest (конфигурация CorsConfiguration, запрос httpservletRequest, httpservletresponse) Throws ioexception {if (! Corsutils.iscorsrequest (request)) {return true;} servletserverhtttpresponse serverresponse = new Servletserverhttpresponse (response); servletserverhttprequest serverrequest = new Servletserverhttprequest (request); if (webutils.issameorigin (serverRequest)) {logger.debug («Пропустить обработку CORS, запрос-это одно иоригин один»); return true;} if (repplyHascors (serverresponse)) {logger.debug (». Обработка Skip cors, ответный ответ /« access-control-allow-origin /"header /" trueEn; preflightrequest = corsutils.spreflightrequest (request); if (config == null) {if (preflightrequest) {Rejectrequest (serverresponse); return false;} else {return true;}} return handerternal (serverrequest, serverresponsЭтот метод сначала проверяет, является ли это перекрестным запросом, а если это не так, он вернется напрямую. Затем проверяет, находится ли он под одним и тем же доменом, или имеет ли он поле-образное поле, в заголовке ответа, или имеет ли он в запросе, он имеет в запросе. Если условие решения выполнено, запрос отклоняется.
Исходя из этого, мы знаем, что проверка может быть проведена путем установки заголовка ответа ответа с контролем доступа. Мы обрабатываем Prehandle в перехватчике. Добавьте следующий код:
response.setheader ("Access-Control-Oright-Origin", "*");В настоящее время запрос параметров в браузере возвращает 200. Но все еще ошибка:
Заголовок Заголовок Заголовок.
Мы заметили, что в заголовке запроса есть управление доступа к заголовкам: принять, а в заголовке запроса этот заголовок нет. В настоящее время браузер не отправляет запрос по мере необходимости. Попробуйте добавить его в ответ:
response.setheader («Контроль-управляющий головы», «Происхождение, x-requested-with, тип контента, прием»);
Выполнение Успешное: Object {userId: 123, имя пользователя: "AdminupDate-Wangdachui"}.
До сих пор: мы используем принцип анализа, чтобы позволить SpringMVC для достижения междомена без каких-либо изменений в исходной реализации и клиентском коде.
Springmvc 4
Кроме того, в ссылке 2 Springmvc4 предоставляет очень удобный метод для реализации междоменного.
Используйте аннотации в запросах. @Crossorigin (Origins = "http: // localhost: 9000")
Глобальная реализация. Определение класса наследование webmvcconfigureradapter
Общедоступный класс CorsConfigurerAdapter Extends webmvcconfigurerAdapter {@OverridePublic void addCorsMappings (реестр CorsRegistry) {Registry.Addmapping ("/api/*"). AldorIgins ("*");}}Введите класс в контейнер:
<Bean> </bean>
Суммировать
Выше приведено все подробное объяснение реализации пружины и обработки междоменного кода запроса. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!