Eine normale Anfrage
Kürzlich müssen andere eine Funktion unseres Systems aufrufen, und die andere Partei hofft, eine API bereitzustellen, damit sie Daten aktualisieren können. Da dieser Klassenkamerad ein Kundenentwickler ist, hat er einen Code, der dem folgenden ähnelt.
@RequestMapping (methode = requestMethod.post, value = "/update.json", procies = minytype.application_json_value) public @Responbody contacter update (@RequestBody contacter contacterro) {logger.debug ("{{} contacterro. contacterro. (contacterro.getUerId () == 123) {contacterro.setusername ("adminUpdate-wangdachui");} return contacterro;}Der Client initiiert eine HTTP -Anforderung über Code, um ihn aufzurufen. Dann fragte der Schüler: Er hoffte, JS-Anrufe durch den Browser zu verwenden, also gab es ein Cross-Domain-Problem.
Warum Cross-Domain
Einfach ausgedrückt, der Browser beschränkt den Zugriff auf den JS -Code unter Standort A, um die AJAX -Anfrage an die URL unter Standort B zu stellen. Wenn der aktuelle Domänenname www.abc.com ist, kann der JS -Code, der in der aktuellen Umgebung ausgeführt wird, aus Sicherheitsgründen nicht auf die Ressourcen unter dem Domänennamen www.zzz.com zugreifen.
Zum Beispiel: Der folgende Code kann verwendet werden, um die Schnittstelle normalerweise über JS -Code unter diesem Domänennamen aufzurufen
(function () {var url = "http: // localhost: 8080/api/home/update.json"; var data = {"userId": 123, "Benutzername": "Wangdachui"}; 'application/json'}). Done (Funktion (Ergebnis) {console.log ("Erfolg"); console.log (result);}). fail (function () {console.log ("error");})}) ())Die Ausgabe ist:
Objekt {userId: 123, Benutzername: "adminUpdate-wangdachui"}Wenn Sie unter anderen Domain -Namen zugreifen, wird jedoch ein Fehler verursacht:
Optionen http: // localhost: 8080/api/home/update.jsonxmlhttpRequest kann nicht laden http: // localhost: 8080/api/home/update.json. Antwort auf die Anforderung vor dem Flug passt nicht über die Zugriffskontrollprüfung hin: Nein "Access-Control-Allow-Origin-Header" ist in der angeforderten Ressource vorhanden. Der Ursprung 'Null' ist daher nicht zulässig. Die Antwort hatte HTTP -Statuscode 403.
Lösung
JSONP
Die Verwendung von JSONP bis Cross-Domain ist eine relativ häufige Art und Weise, aber wenn die Schnittstelle geschrieben wurde, müssen sowohl der Server als auch die Anrufseite mit der ursprünglichen Schnittstelle transformiert und kompatibel sein, was etwas zu viel Arbeit ist, sodass wir andere Methoden betrachten.
CORS -Protokoll
Laut Referenzen: Jede Seite muss eine HTTP-Header mit dem Namen 'Access-Control-Allow-Origin' zurückgeben, um den Zugriff auf die Site im Fremdbereich zu ermöglichen. Sie können nur begrenzte Ressourcen und begrenzte Zugriffe außerhalb der Domäne aufdecken. Im COR -Modus kann die Verantwortung für die Zugriffskontrolle in die Hände des Seitenentwicklers und nicht in den Serveradministrator gelegt werden. Seitentwickler müssen natürlich einen speziellen Verarbeitungscode schreiben, um den Zugriff auf die äußere Welt zu ermöglichen. Wir können es verstehen als: Wenn eine Anfrage einen Cross-Domänen-Zugriff ermöglichen muss, müssen Sie den HTTP-Header im HTTP-Header auf die Zugriffskontrolle festlegen, um zu entscheiden, auf welche Websites zugegriffen werden sollen. Wenn Sie Anforderungen von www.foo.com an Cross-Domain zulassen müssen, können Sie feststellen: Access-control-allow-origin: http://www.foo.com. Oder Zugangskontroll-Allow-Origin: *. CORS wird in den meisten modernen Browsern als Teil von HTML5 unterstützt.
CORS hat die folgenden allgemeinen Header
Access-Control-Owl-Origin: http: //foo.orgaccess-control-max-altern: 3628800Access-control-allow-Methods: Get, put, deleteAccess-control-alow-header: content-type "access-control-orn-origin" tom. Anfragen. "Zugriffskontroll-Max-Zeitalter" zeigt an, dass innerhalb von 3628800 Sekunden keine Vorabanfragen erforderlich sind. Das Ergebnis "Access-Control-Allow-Methoden" gibt an, dass es an Anfragen von Get-, Put-, Löschen von Out-Domain-Anforderungen "Zugriffskontroll-Control-Allow-Header" ermöglicht wird
Basic CORS -Prozess
Zunächst wird eine Vorfluganforderung ausgestellt, die zunächst eine Optionsmethode und eine Anforderung mit dem Header "Origin" an den Ressourcenserver ausgeht. Diese Antwort kann die COR -Anforderungsmethode, den HTTP -Header und die Überprüfungsinformationen steuern. Eine echte fremde Domain -Anfrage wird erst nachlässt, nachdem die Anfrage zulässig ist.
Frühlings -MVC unterstützt CORs
Antwort auf die Anforderung vor dem Flug passt nicht über die Zugriffskontrollprüfung hin: Nein "Access-Control-Allow-Origin-Header" ist in der angeforderten Ressource vorhanden. Der Ursprung 'Null' ist daher nicht zulässig. Die Antwort hatte HTTP -Statuscode 403.
Aus der obigen Fehlermeldung können wir erkennen, dass der direkte Grund darin besteht, dass es im Anforderungsheader keinen Header für Zugriffskontroll-Owl-Origin-Orientierstoffe gibt. Unsere direkte Idee ist es also, diesen Header dem Anforderungsheader hinzuzufügen. Der Server kann 403 zurückgeben, was angibt, dass der Server die Anforderung tatsächlich verarbeitet hat.
MVC Interceptor
Zunächst konfigurieren wir einen Interceptor, um die Anforderung abzufangen und die Headerinformationen der Anforderung abzusetzen.
DEBUG Requesturl: /api/home/update.json Debug-Methode: Optionen Debug-Header Host: Localhost: 8080 Debug-Header-Verbindung: Keep-Alive Debug-Header Cache-Kontroll: Max-AGE = 0 Debug-Header-Access-Kontroll-Kontroll-Request-Request-Method: Windows-Header-Debug-Debug-Header: Mozilla/5.-NULL-Debug-Debug. Applewebkit/537.36 (KHTML, wie Gecko) Chrome/49.0.2623.87 Safari/537.36 Debug-Header Access-Control-Request-Header: Akzeptieren, Inhalts-Typ-Debug-Header Akzeptieren: Akzeptieren Sprache: ZH-CN, ZH; Q = 0,8, EN; Q = 0,6
Das Drucken des Protokolls nach Posthandle ergab, dass der Status der Antwort zu diesem Zeitpunkt 403 beträgt. Die Verfolgung von SpringMVC -Codes ergab, dass HandlexexexexexexexcutionChain in org.springframework.web.servlet.dispatcherServlet.Dodispatch basierend auf Anfrage erhalten wird. Nachdem SpringMVC einen regulären Prozessor erworben hat, wird er überprüfen, ob es sich um eine Cross-Domain-Anfrage handelt. In diesem Fall ersetzt es die ursprüngliche Instanz.
@Overridepublic final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {Object handler = getHandlerInternal(request);if (handler == null) {handler = getDefaultHandler();}if (handler == null) {return null;}// Bean name or resolved handler?if (handler instanceof String) {String Handlername = (String) Handler; Handler = GetApplicationContext (). GetBean (Handlername);} HandlexexexcutionChain ExecutionChain = GetHandLexexeCutionChain (Handler, Anfrage); this.corsconfigSource.getCorsConfiguration (Anfrage); CorsConfiguration HandlerConfig = GetCorsConfiguration (Handler, Anfrage); corsConfiguration config = (globalConfig! = null? globalconfig.combine (HandlerConfig): HandlerConfig. config);} return ExecutionChain;}Die Überprüfungsmethode ist auch sehr einfach, dh prüfen Sie, ob im Anforderungsheader ein Feldfeld vorhanden ist.
public static boolean iscorsRequest (httpServletRequest -Anforderung) {return (request.getheader (httpheaders.origin)! = null);}Die Anfrage wird dann an httprequestHandlerAdapter.Handle zur Verarbeitung übergeben, und verschiedene Logiken werden gemäß dem Griff verarbeitet. Das vorherige Urteil basiert auf dem Anfrage-Header als Cross-Domain-Anfrage. Der erhaltene Handler ist Preflyhandler, der als:
@Overridepublic void HandleRequest (httpServletRequest Request, httpServletResponse -Antwort) löst IOException {corSprocessor.ProcessRequest aus (this.config, Anfrage, Antwort);}Weiter nachverfolgen
@OverridePublic Boolean ProcessRequest (corsConfiguration config, httpServletRequest -Anforderung, httpServletResponse -Antwort) löst IOException {if (! CorsUtils.iscorsRequest (Anfrage)) {return true;} servletServerhtPespRePrPePresponsponse = new ServletServerhttPresponse (Antwort); ServletServerHtTprequest serverRequest = new ServletServerHttprequest (Anfrage); if (webutils.ISSameOrigin (ServerRequest)) {Logger.debug ("CORS-Verarbeitung überspringen, Anforderung ist ein gleiches Ursprung"); Return true;} if (reactingHascors (serverResponse)) {Logger.debug ("Skip cors, Reaktion, Reaktion, die bereits Zugriffs-CONTROLEAN-BOOLEAN-BOOLEAN /" HEACER "; = CorsUtils.isPreFlightRequest(request);if (config == null) {if (preFlightRequest) {rejectRequest(serverResponse);return false;} else {return true;}}return handleInternal(serverRequest, serverResponse, config, preFlightRequest);}Diese Methode prüft zunächst, ob es sich um eine Cross-Domain-Anfrage handelt, und wenn dies nicht der Fall ist, wird sie direkt zurückgegeben. Überprüfen Sie dann, ob es sich unter derselben Domäne befindet oder ob es über das Feld "Zugriffskontroll-Owl-Origin-Origin im Antwortheader" verfügt oder ob es in der Anforderung die Zugriffskontroll-Request-Methode enthält. Wenn die Urteilsbedingung erfüllt ist, wird die Anfrage abgelehnt.
Daraus wissen wir, dass der Scheck über die Einstellung des Headers der Access-Control-Allow-Origin der Antwort vor dem Scheck übergeben werden kann. Wir kümmern uns um Prehandle im Interceptor. Fügen Sie den folgenden Code hinzu:
response.setheader ("Access-Control-Allow-Origin", "*");Zu diesem Zeitpunkt gibt die Optionsanforderung im Browser 200 zurück, aber dennoch ein Fehler:
Der Inhalt des Anforderungs-Header-Feldes ist nicht durch Zugriffskontroll-Allow-Header in der Reaktion vor dem Flug zulässig.
Wir haben festgestellt, dass es Zugriffskontroll-Request-Header gibt: Akzeptieren Sie den Inhalts-Typ im Anforderungsheader, dieser Anfrage-Header jedoch nicht. Zu diesem Zeitpunkt sendet der Browser die Anfrage nicht nach Bedarf. Versuchen Sie, es der Antwort hinzuzufügen:
Response.Setheader ("Access-Control-Allow-Header", "Origin, X-Requested-with, Content-Typ, Accept");Ausführung erfolgreich: Objekt {userId: 123, Benutzername: "adminUpdate-wangdachui"}.
Bisher: Wir verwenden das Analyseprinzip, um SpringMVC zu ermöglichen, Cross-Domain zu erreichen, ohne Änderungen der ursprünglichen Implementierung und des Client-Code zu ändern.
Springmvc 4
Darüber hinaus bietet SpringMVC4 in Referenz 2 eine sehr bequeme Methode zur Implementierung von Cross-Domain.
Verwenden Sie Annotationen in RequestMapping. @Crossorigin (Origins = "http: // localhost: 9000")
Globale Implementierung. Definitionsklasse Vererbung webmvcconFigerAdapter
Public Class CorsConFigurerAdapter erweitert webmvcconFigurerAdapter {@Overridepublic void addCorsMappings (CorsRegistry -Registrierung) {Registry.Addmapping ("/api/*"). Denorigines ("*");}}}}}}}}}}}}}}}}}}Injizieren Sie die Klasse in den Container:
<bean> </bean>
Zusammenfassen
Das obige ist alle detaillierte Erläuterungen für die Implementierung und Verarbeitung des Cross-Domänen-Anforderungscode für Feder. Ich hoffe, es wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!