仕事において、クロスドメインの問題を解決するにはどうすればよいでしょうか?


実際のプロジェクトでは、フロントエンドとバックエンドが 2 つの異なるプロジェクトに分割され、それぞれが異なるドメイン名でデプロイされるため、クロスドメインの問題も発生します。

問題が発生したので、問題を根本的に解決する必要がありますが、解決策について話す前に、クロスドメインとは何かを理解する必要があります。

クロスドメインとは何ですか?

クロスドメインとは、ブラウザーが他の Web サイトからのスクリプトを実行できないことを意味します。これは、ブラウザーの同一生成元ポリシー (JavaScript に対してブラウザーによって課されるセキュリティ制限) が原因で発生します。

同一生成元ポリシーとは何ですか?

いわゆる相同性とは、プロトコル、ドメイン名、ポート番号がすべて同じであるが、そのうちの 1 つが異なる限り、それらはすべて同じ起源ではないことを指します。

同一オリジン ポリシーは、Netscape によって提案されたセキュリティ ポリシーです。これはブラウザの中核であり、最も基本的なセキュリティ機能です。同一オリジン ポリシーが存在しない場合、ブラウザの通常の機能に影響が出る可能性があります。現在、サポートされているすべてのブラウザが対応しています。 JavaScript はこの戦略を使用します。

ブラウザはスクリプトを実行するときに、そのスクリプトがどのページに属しているか、つまり同じオリジンのものであるかどうかをチェックし、同じオリジンのスクリプトのみが実行されます。同じオリジンではないスクリプトがリクエストした場合は、データが存在しない場合、ブラウザは例外を報告し、アクセスの拒否を促します。

  • http://www.a.com/index.html呼び出しhttp://www.a.com/user.jspプロトコル、ドメイン名、およびポート番号はすべて同じであり、発行元も同じです。

  • https://www.a.com/index.html呼び出しhttp://www.a.com/user.jspプロトコルは異なり、同じ起源のものではありません。

  • http://www.a.com:8080/index.html呼び出しhttp://www.a.com:8081/user.jspポートは異なっており、同じ発信元ではありません。

  • http://www.a.com/index.html呼び出し元のhttp://www.b.com/user.jspドメイン名は異なり、同じ起源のものではありません。

  • http://localhost:8080/index.html呼び出しhttp://127.0.0.1:8080/user.jsplocalhost は 127.0.0.1 に相当しますが、発信元が同じではありません。

同一生成元ポリシーによって制限される状況:

  1. Cookie、LocalStorage、IndexDB を読み取れません

  2. DOMおよびJsオブジェクトが取得できない

  3. AJAXリクエストを送信できませんでした

注: img、iframe、script などのタグの src 属性は特殊なケースであり、同じ生成元ではない Web サイトのリソースにアクセスできます。

クロスドメインプロセス

d962ac838197193520f073411ac9393.png

クロスドメインアクセスの例

2 つの Web サイトがあり、Web サイト A はhttp://localhost:8080ローカル IP ポート 8080 に展開され、Web サイト B はhttp://localhost:8081ローカル IP ポート 8081 に展開されているとします。

Web サイト B のページが Web サイト A の情報にアクセスしたいとすると、ページは次のように表示されます。

画像.png

上記のエラー メッセージから、クロスドメインの問題が発生していることがわかります。

クロスドメインの問題を解決するにはどうすればよいでしょうか?

1.フィルター

Filter フィルターを使用してサービス リクエストをフィルター処理し、応答ヘッダー (応答ヘッダー) の Access-Control-Allow-Origin 属性をリクエスタに設定して、クロスドメイン アクセスが許可されていることを宣言します。

@WebFilter
public class CorsFilter implements Filter {
    
      

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    
      
        HttpServletResponse response = (HttpServletResponse) res;  
        response.setHeader("Access-Control-Allow-Origin", "*");  
        response.setHeader("Access-Control-Allow-Methods", "*");  
        response.setHeader("Access-Control-Max-Age", "3600");  
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res);  
    }  
}

2. HandlerInterceptorAdapterの継承

@Component
public class CrossInterceptor extends HandlerInterceptorAdapter {
    
    

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
    }
}

3. WebMvcConfigurer を実装する

@Configuration
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
public class AppConfig implements WebMvcConfigurer {
    
    

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
    
        registry.addMapping("/**")  // 拦截所有的请求
                .allowedOrigins("http://www.abc.com")  // 可跨域的域名,可以为 *
                .allowCredentials(true)
                .allowedMethods("*")   // 允许跨域的方法,可以单独配置
                .allowedHeaders("*");  // 允许跨域的请求头,可以单独配置
    }
}

4. Nginx 構成を使用する

location / {

   add_header Access-Control-Allow-Origin *;
   add_header Access-Control-Allow-Headers X-Requested-With;
   add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;

   if ($request_method = 'OPTIONS') {
     return 204;
   }
}

5.@CrossOrgin注釈を使用する

一部のインターフェイスのみをドメイン間で共有し、構成を使用して管理したくない場合は、この方法を使用できます。

コントローラーでの使用

@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    
    

	@GetMapping("/{id}")
	public User get(@PathVariable Long id) {
    
    
		
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
    
    

	}
}

特定のインターフェイスで使用する

@RestController
@RequestMapping("/user")
public class UserController {
    
    

	@CrossOrigin
	@GetMapping("/{id}")
	public User get(@PathVariable Long id) {
    
    
		
	}

	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
    
    

	}
}

要約する

フロントエンドソリューション

  1. JSONP を使用してクロスドメイン呼び出しを実装します。
  2. NodeJS サーバーをサービス プロキシとして使用し、フロントエンドが NodeJS サーバーへのリクエストを開始し、NodeJS サーバー プロキシがそのリクエストをバックエンド サーバーに転送します。

バックエンドソリューション

  • Nginx リバースプロキシはクロスドメインを解決します
  • サーバー設定Response Header(応答ヘッダー) Access-Control-Allow-Origin
  • @CrossOriginクロスドメイン アクセスを必要とするクラスおよびメソッドでクロスドメイン アクセスを許可します ( Spring でのアノテーションの使用など)。
  • Spring Web の CorsFilter (Spring MVC、Spring Boot に適用) を継承して使用します。
  • WebMvcConfigurer インターフェイスを実装します (Spring Boot 用)。

おすすめ

転載: blog.csdn.net/jiang_wang01/article/details/131366267