フロントエンド | クロスドメインの問題に対するフロントエンドおよびバックエンドのソリューション


01 クロスドメインの問題とは何ですか?

クロスドメインの問題とは、フロントエンドとバックエンドの開発において、ブラウザーがクロスドメイン リクエストを開始するときに、同一オリジン ポリシーによって制限され、リクエストが失敗する状況を指します。同一オリジン ポリシーは、異なるドメイン名、異なるポート、または異なるプロトコル間でのブラウザによるクロスドメイン リソース アクセスを制限するセキュリティ メカニズムです。

同一オリジン ポリシーでは、要求されたドメイン名、ポート、およびプロトコルがまったく同じである必要があり、それらがまったく同じである場合にのみ、ブラウザーはクロスドメイン リクエストを許可します。それ以外の場合、ブラウザは、悪意のある Web サイトがユーザーの機密情報を取得したり、悪意のある操作を実行したりするのを防ぐために、クロスドメイン リクエストへの応答を拒否します。

02 クロスドメインの問題の例

例: フロントエンド サービスのアクセス パスは でhttp://localhost:8070、バックエンド サービスのアクセス パスは ですhttp://localhost:8080。フロントエンド ページがバックエンド サービスにリクエストを送信する必要がある場合、クロスドメイン エラーが発生します。報告される。

コード例は次のとおりです。

  • フロントエンド(エクスプレス)
    • main.js

      import express from 'express'			// 导入前端服务器
      const app = express()					// 创建前端服务器对象
      app.use(express.static("./static"))		// 所有请求发向前端服务器的静态资源
      app.listen(8070)						// 8070端口作为请求端口
      
    • デモ.html

      <body>
      ...
      <!--js部分-->
      <script>
          fetch("http://localhost:8080/api/students") // 这里会出现跨域问题
              .then(resp => resp.json())
              .then(data => {
                
                ...})
      </script>
      </body>
      
  • バックエンド (SpringBoot)
    • Student.java

      // 省略 构造方法 getter setter
      public class Student {
              
              
          private int id;
          private String name;
          private String sex;
          private int age;
      }
      
    • テストコントローラー.java

      // 浏览器访问http://localhost:8080/api/students
      @RestController()
      @RequestMapping("api")
      public class TestController {
              
              
          @GetMapping("/students")
          public ResponseEntity<ArrayList<Student>> getStudents() {
              
              
              Student s1 = new Student(1, "张三", "男", 18);// s2 s3 s4 略
              ArrayList<Student> students = new ArrayList<>(List.of(new Student[]{
              
              s1, s2, s3, s4}));
              return ResponseEntity.ok(students);
          }
      }
      

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

バックエンドは@CrossOriginアノテーションを使用して、アクセスできるドメインを指定できます。デフォルトの構成では、すべてのドメインがアクセス可能です。
このアノテーションをコントローラー クラスまたは対応するインターフェイス メソッドに追加するだけです。

  • テストコントローラー.java
    @RestController()
    @RequestMapping("api")
    @CrossOrigin("http://localhost:8070") // 可以不写括号和参数 默认表示允许所有域
    public class TestController {
          
          
    
    	@GetMapping("/students")
    	// 或者加在这里 仅对某接口生效
    	public ResponseEntity<ArrayList<Student>> getStudents() {
          
          
    		Student s1 = new Student(1, "张三", "男", 18);// s2 s3 s4 略
    		ArrayList<Student> students = new ArrayList<>(List.of(new Student[]{
          
          s1, s2, s3, s4}));
    		return ResponseEntity.ok(students);
    	}
    	
    }
    

変更できるのはバックエンドのみで、フロントエンドのコードは変更されません。

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

フロントエンドの解決策はプロキシを使用することです。変更する必要があるのはフロントエンド コードのみであり、バックエンドでは @CrossOrigin アノテーションを使用する必要はなく、バックエンド コードは変更されません。
(個人的にはフロントエンド ソリューションの使用をお勧めします)

  • npmインストールプラグイン

    # 命令行安装必要的库
    npm install http-proxy-middleware --save-dev
    
  • main.jsで
    、元のコードに import と app.use() を追加します。

    import express from 'express'
    // [新增] 导入中间件
    import {
          
          createProxyMiddleware} from "http-proxy-middleware"
    const app = express()
    // [新增] 设置路径中以/api开头的请求进行跨域代理
    app.use("/api", createProxyMiddleware({
          
          target: "http://localhost:8080", changeOrigin: true}))
    app.use(express.static("./static")) // 其他请求走之前默认的配置
    app.listen(8070)
    
  • demo.html
    HTML ページは、リクエストを送信する部分を変更します

    <body>
    ...
    <!--js部分-->
    <script>
        fetch("/api/students") // 因为是代理 所以请求是发向前端服务器的代理中间件 直接写uri路径即可
            .then(resp => resp.json())
            .then(data => {
            
            ...})
    </script>
    </body>
    

詳細情報: @CrossOrigin アノテーションについて

(ChatGPT経由)

Java では、@CrossOriginクロスドメイン要求を処理するためにアノテーションが使用されます。これは、コントローラー クラスまたはハンドラー メソッドでクロスドメイン リクエストのサポートを有効にするために Spring フレームワークによって提供されるアノテーションの 1 つです。

注釈を使用して@CrossOrigin、許可されたドメイン名、メソッド、リクエスト ヘッダーなどを含む、クロスドメイン リクエストを許可するルールを構成します。@CrossOriginアノテーションの共通プロパティは次のとおりです。

  • value: クロスドメインリクエストを許可するオリジンを指定します。これには、単一の文字列または文字列の配列を指定できます。たとえば、value = "http://example.com"またはvalue = {"http://example.com", "http://another-domain.com"}
  • origins:value属性と同じで、クロスドメインリクエストを許可するオリジンを指定するために使用されます。
  • methods: 許可される HTTP リクエスト メソッドを指定します。これは、単一の文字列または文字列の配列にすることができます。デフォルトでは、すべてのメソッド (GET、POST など) が許可されます。たとえば、methods = RequestMethod.GETまたはmethods = {RequestMethod.GET, RequestMethod.POST}
  • allowedHeaders: 許可されるリクエスト ヘッダー情報を指定します。これは、単一の文字列または文字列の配列にすることができます。デフォルトでは、すべてのヘッダーが許可されます。たとえば、allowedHeaders = "Authorization"またはallowedHeaders = {"Authorization", "Content-Type"}
  • exposedHeaders: クライアントに公開できる応答ヘッダー情報を指定します。これは、単一の文字列または文字列の配列にすることができます。
  • allowCredentials: クロスドメイン要求のサーバーへの認証資格情報 (Cookie など) の送信を許可するかどうかを指定します。デフォルトは false で、資格情報の送信が許可されないことを意味します。
  • maxAge: プリフライトリクエストの最大キャッシュ時間を秒単位で指定します。プリフライト リクエストは、クロスドメイン リクエストが安全かどうかを確認するために使用されるリクエストです。

アノテーションを使用した例を次に示します@CrossOrigin

@RestController
@CrossOrigin(origins = "http://example.com", methods = RequestMethod.GET, allowedHeaders = "Authorization")
public class MyController {
    
    
  
  @GetMapping("/data")
  public ResponseEntity<String> getData() {
    
    
    // 处理请求并返回响应
  }
  
  // 其他处理方法...
}

上記の例では、@CrossOriginアノテーションがMyControllerコントローラー クラスに適用され、許可されるクロスドメイン リクエストのソースが「http://example.com」、許可されるメソッドが GET、許可されるリクエスト ヘッダーが Authorization であることが指定されます。このようにすると、「http://example.com」からの GET リクエストと、Authorization リクエスト ヘッダーを含むリクエストのみが、/dataドメインを越えてインターフェイスにアクセスできます。

アノテーションを使用すると@CrossOrigin、クロスドメイン リクエストを簡単に処理できますが、クロスドメイン リクエストがもたらす可能性のあるセキュリティ リスクに注意する必要があるため、クロスドメイン リクエストを許可するように構成する場合は慎重に検討する必要があります。

おすすめ

転載: blog.csdn.net/xuzhongyi103/article/details/131614821
おすすめ