通常のリクエスト
最近、他の人は私たちのシステムの関数を呼び出す必要があり、他の当事者はデータを更新できるようにAPIを提供したいと考えています。このクラスメートはクライアント開発者であるため、彼は次のようなコードを持っています。
@RequestMapping(requestMethod.post、value = "/update.json"、生産= mediatype.application_json_value)public == 123){contacterro.setUsername( "adminupdate-wangdachui");} return contacterro;}クライアントは、コードを介してHTTP要求を開始して呼び出します。その後、学生は尋ねました:彼はブラウザを介してJSコールを使用したいと思っていたので、クロスドメインの問題がありました。
なぜクロスドメイン
簡単に言えば、ブラウザはサイトAのJSコードへのアクセスを制限して、サイトBの下のURLにAjax要求を行います。現在のドメイン名が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、type: 'post'、datatype: 'jsatype:' json '、Datape: 'application/json'})出力は次のとおりです。
object {userid:123、username: "adminupdate-wangdachui"}ただし、他のドメイン名でアクセスすると、エラーが発生します。
オプションhttp:// localhost:8080/api/home/update.jsonxmlhttprequestはhttp:// localhost:8080/api/home/update.jsonをロードできません。プリライトリクエストへの応答は、アクセス制御チェックに合格しません。「アクセス制御コントロール - アロウオリジン」ヘッダーは、要求されたリソースに存在しません。したがって、Originの「ヌル」はアクセスを許可されていません。応答には、HTTPステータスコード403がありました。
解決
jsonp
JSONPを使用することは比較的一般的な方法ですが、インターフェイスが記述されている場合、サーバーとコール側の両方を変換して元のインターフェイスと互換性がある必要があります。
CORSプロトコル
参考文献によると、各ページは、「Access-Control-Allow-Origin」という名前のHTTPヘッダーを返して、外部ドメインのサイトへのアクセスを許可する必要があります。限られたリソースと限られたドメインのサイトアクセスを公開することができます。 CORモードでは、アクセス制御の責任は、サーバー管理者ではなく、ページ開発者の手に配置できます。もちろん、ページ開発者は、外の世界へのアクセスを許可するために特別な処理コードを作成する必要があります。リクエストがクロスドメインアクセスを許可する必要がある場合は、HTTPヘッダーにアクセス制御コントロールオリジンを設定して、アクセスを許可するサイトを決定する必要があります。 www.foo.comからクロスドメインへのリクエストを許可する必要がある場合は、次のように設定できます。Access-Control-Allow-Origin:http://www.foo.com。またはアクセスコントロールアロウオリジン: *。 CORSは、HTML5の一部としてほとんどの最新のブラウザでサポートされています。
CORSには次の共通ヘッダーがあります
Access-Control-Allow-Origin:http://foo.orgacess-control-max-age:3628800Access-control-allow-methods:get、deleteaccess-control-headers:content-type "access-control-origin"リクエスト。 「Access-Control-Max-age」は、3628800秒以内に、事前チェックリクエストが不要であることを示しています。結果の「Access-Control-Allow-Methods」は、「Access-Control-Allow-Headers」という「Access-Domainリクエスト」の取得、配置、削除を許可することを示しています。
基本的なCORSプロセス
最初に、最初にオプションメソッドを発行し、リソースサーバーへの「Origin」ヘッダーを含むリクエストを最初に発行します。この返信は、CORリクエストメソッド、HTTPヘッダー、および検証情報を制御できます。実際の外国ドメイン要求は、リクエストが許可された後にのみ開始されます。
スプリングMVCはCORSをサポートします
プリライトリクエストへの応答は、アクセス制御チェックに合格しません。「アクセス制御コントロール - アロウオリジン」ヘッダーは、要求されたリソースに存在しません。したがって、Originの「ヌル」はアクセスを許可されていません。応答には、HTTPステータスコード403がありました。
上記のエラーメッセージから、直接的な理由は、リクエストヘッダーにアクセスコントロールオロウオリジンヘッダーがないことであることがわかります。したがって、私たちの直接的なアイデアは、このヘッダーをリクエストヘッダーに追加することです。サーバーは403を返すことができ、サーバーが実際にリクエストを処理したことを示します。
MVCインターセプター
まず、リクエストをインターセプトし、リクエストのヘッダー情報をログに記録するようにインターセプターを構成します。
debug requesturl:/api/home/update.jsonデバッグメソッド:オプションデバッグヘッダーホスト:ローカルホスト:8080デバッグヘッダー接続:キープアライブデバッグヘッダーキャッシュコントロール:0デバッグヘッダーアクセス - レクスト - メソッド:ポストデブラヘッダーオリジン:null debug header cules usere-agenter-agenter-agenter-agenter-jules-agenter-agenter-agenter-agenter-agenter-jilla/5.0(5.0(5.0) AppleWebkit/537.36(Khtml、GeckoのようなKhtml)Chrome/49.0.2623.87 Safari/537.36 Debug Header Access-Control-Request-Headers:Accept、Content-Type Debug Header Accept:*/* Debug Head-Encodin Accept-Language:Zh-cn、zh; q = 0.8、en; q = 0.6
ログを印刷して、この時点で応答のステータスが403であることがわかりました。 SpringMVCコードの追跡では、org.springframework.web.servlet.dispatcherservlet.dodispatchで、リクエストに基づいてHandLerexecutionChainが取得されることがわかりました。 SpringMVCが通常のプロセッサを取得した後、それがクロスドメイン要求であるかどうかを確認します。もしそうなら、それは元のインスタンスを置き換えます。
@OverridePublic Final HandLerexecutionChain Gethandler(httpservletrequest request)throws {object handler = gethandlerinternal(request); if(handler == null){handler = getDefaultherr();} if(handler == null? {string handlername =(string)handler; handler = getApplicationContext()。getBean(handlername);} handlerexecutionchain executionchain = gethandlerexecutionchain(handler、request); if(corsutils.iscorrequest(request)){corsconfiguration globalconfig = corsconfiguration this.corsconfigsource.getCorsConfiguration(request); corsconconfiguration handlerconfig = getCorsConfiguration(ハンドラー、リクエスト); corsconfiguration config =(globalconfig!= null?globalconfig.combine(handlerconfig):handleconfig); executionchain = gettutionchain = getcorshandlerexecutycuteChain config);} return executionchain;}チェック方法も非常に単純です。つまり、リクエストヘッダーにオリジンフィールドがあるかどうかを確認します。
public static boolean iscorrequest(httpservletrequest request){return(request.getheader(httpheaders.origin)!= null);}その後、リクエストは処理のためにhttprequesthandleradapter.handleに引き渡され、ハンドルに従ってさまざまなロジックが処理されます。以前の判断は、クロスドメイン要求としてのリクエストヘッダーに基づいています。取得したハンドラーは、次のように実装されています。
@overridepublic void handlerequest(httpservletrequest request、httpservletresponse応答)はioexception {corsprocessor.processrequest(this.config、request、response);}フォローアップを続けます
@OverridePublic Boolean ProcessRequest(CORSCONFIGURATION CONFIG、HTTPSERVLETREQUESTリクエスト、HTTPSERVLETRESPONSE RESPONSE)IOEXCEPTION {if(!corsutils.iscorsRequest(request){return true;} servletserverhtttttesponse = new new new servletserverhttpresponse(response); servletserverhttprequest serverRequest = new servletserverhttprequest(request); if(webutils.issameorigin(serverRequest)){logger.debug( "skip cors処理、リクエストは同じオリジンの1つです"); return true;} if(responsehascors(serverResponse)){logger.debug( "cors cors処理、応答は既にcassion-control-oligin / preflightrequest = corsutils.ispreflightrequest(request); if(config == null){if(preflightrequest){rejectRequest(serverResponse); return false;} els {return true;}} return handle -internal(serverRequest、serverResponse、configest、configest);}この方法では、最初にクロスドメイン要求であるかどうか、そうでない場合は直接戻ります。次に、同じドメインの下にあるかどうか、または応答ヘッダーにアクセス制御コントロールオリジンフィールドがあるのか、リクエストにアクセスコントロールリクエストメソッドがあるのかを確認します。判断条件が満たされた場合、要求は拒否されます。
このことから、チェックの前に応答のアクセスコントロールオリジンヘッダーを設定することで、チェックを渡すことができることを知っています。インターセプターのプリハンドルを処理します。次のコードを追加します。
Response.setheader( "Access-Control-allow-Origin"、 "*");
この時点で、ブラウザのオプション要求は200を返します。ただし、エラーは次のとおりです。
リクエストヘッダーフィールドコンテンツタイプは、プレフィライト応答でアクセス制御 - アロウヘッダーによって許可されません。
アクセスコントロール - レクエストヘッダーがあることに気付きました。リクエストヘッダーのコンテンツタイプを受け入れましたが、このリクエストヘッダーは受け入れません。現時点では、ブラウザは必要に応じてリクエストを送信しません。応答に追加してみてください。
Response.setheader( "Access-control-allow-headers"、 "Origin、x-requested-with、content-type、Accept");
実行成功:object {userid:123、username: "adminupdate-wangdachui"}。
これまでのところ、分析原則を使用して、SpringMVCがクロスドメインを実現できるようにします。
springmvc 4
さらに、参照2では、SpringMVC4は、クロスドメインを実装するための非常に便利な方法を提供します。
リクエストマッピングで注釈を使用します。 @crossorigin(Origins = "http:// localhost:9000")
グローバル実装。定義クラス継承webmvcconfigureradapter
パブリッククラスのcorsconfigurerAdapter拡張webmvcconfigureradapter {@overridepublic addcorsmappings(corsregistry registry){registry.addmapping( "/api/*")。クラスをコンテナに注入します。
<bean> </bean>
要約します
上記は、春の実装と処理クロスドメイン要求コードのすべての詳細な説明です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!