記事ディレクトリ
Java クロスドメイン問題の解決策
1. クロスドメインとは
クロスドメインとは、ブラウザーが他の Web サイトからスクリプトを実行できず、あるドメイン名の Web ページから別のドメイン名のリソースをリクエストする場合、ドメイン名、ポート、またはプロトコルの違いがクロスドメインであることを指します。クロスドメインは、ブラウザーによって課されるセキュリティ制限であるブラウザーの同一オリジン ポリシーによって発生します。ページ a はページ b のリソースを取得しようとしています。ページ a とページ b のプロトコル、ドメイン名、ポート、およびサブドメイン名が異なる場合、実行されるアクセス アクションはすべてクロスドメインになります。
2. 一般的なクロスドメインの例
現在のページの URL | リクエストされたページのURL | クロスドメインかどうか | 理由 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | いいえ | 同じソース (同じプロトコル、ドメイン名、ポート番号) |
http://www.test.com/ | https://www.test.com/index.html | クロスドメイン | プロトコルが異なります(http/https) |
http://www.test.com/ | http://www.baidu.com/ | クロスドメイン | ドメイン名が異なります(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | クロスドメイン | ドメイン名が異なります(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | クロスドメイン | 異なるポート番号 (8080/7001) |
3. Java バックエンド ソリューション
1. WebMvcConfigurerを実装する
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 拦截所有的请求
.allowedOrigins("*")// 可跨域的域名,*为所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
.maxAge(3600);
}
}
2. ハンドラーインターセプターの実装
HandlerInterceptorインターフェースを実装したクラスを作成し、preHandleメソッドにレスポンスヘッダーを設定してクロスドメインを実現します。
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
return true;
}
// ...
}
```
这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。
3. フィルターを使用する
javax.servlet.Filter インタフェースを実装したクラスを作成し、doFilter メソッドにレスポンスヘッダを設定してクロスドメインを実現します。
@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", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
// ...
}
````
这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。
注: Filter を使用してクロスドメインを実装する場合、Filter はクロスドメイン リクエストだけでなくすべてのリクエストをインターセプトします。したがって、応答ヘッダーを設定するときは、他のリクエストの通常の処理に影響を与えないように注意する必要があります。よりきめ細かい制御が必要な場合は、 @CrossOrigin アノテーションまたはインターセプターの使用を検討してください。
4. @CrossOrigin アノテーションを使用して、
Spring Boot を使用してクロスドメインを実装する場合、Spring によって提供される @CrossOrigin アノテーションを使用してクロスドメイン アクセスを構成できます。具体的な実装手順は次のとおりです。
(1) クロスドメインを実装する必要があるControllerクラスまたはメソッドに@CrossOriginアノテーションを追加します。例えば:
@CrossOrigin(origins = "http://example.com")
@RestController
public class MyController {
// ...
}
```
这将允许来自 http://example.com 的跨域请求访问 MyController 中的方法。
(2) 複数のドメイン名にアクセスを許可する必要がある場合は、origins パラメータを、アクセスが許可されているすべてのドメイン名を含む配列に設定できます。例えば:
@CrossOrigin(origins = {
"http://example1.com", "http://example2.com"})
@RestController
public class MyController {
// ...
}
```
(3) GET および POST 以外のクロスドメイン HTTP メソッドを許可する必要がある場合は、methods パラメータを使用して、許可されるメソッドのリストを指定できます。例えば:
@CrossOrigin(origins = "http://example.com", methods = {
RequestMethod.GET, RequestMethod.POST})
@RestController
public class MyController {
// ...
}
```
(4) Content-Type 以外のクロスドメイン要求ヘッダーを許可する必要がある場合は、allowedHeaders パラメーターを使用して、許可される要求ヘッダーのリストを指定できます。例えば:
@CrossOrigin(origins = "http://example.com", allowedHeaders = {
"Content-Type", "Authorization"})
@RestController
public class MyController {
// ...
}
```
(5) 認証情報の送信を許可する必要がある場合は、allowCredentials パラメーターを使用して true に設定できます。例えば:
@CrossOrigin(origins = "http://example.com", allowCredentials = "true")
@RestController
public class MyController {
// ...
}
```
5. 応答ヘッダーに Access-Control-Allow-Origin などのフィールドを追加します。
(1) 応答ヘッダーに Access-Control-Allow-Origin フィールドを追加して、特定のドメイン名にアクセスを許可します。たとえば、次のコードでは、ドメイン名http://example.comがAPI にアクセスできるようにします。
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
```
如果希望允许所有域名访问 API,可以将值设置为 *:
(2) 複数のドメイン名による API へのアクセスを許可する必要がある場合は、応答ヘッダーに Access-Control-Allow-Origin フィールドを追加し、アクセスを許可されるすべてのドメイン名を含むリストに設定できます。例えば:
response.setHeader("Access-Control-Allow-Origin", "http://example1.com, http://example2.com");
```
(3) GET および POST 以外のクロスドメイン HTTP メソッドを許可する必要がある場合は、応答ヘッダーに Access-Control-Allow-Methods フィールドを追加して、許可されるメソッドのリストを指定できます。例えば:
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
```
(4) Content-Type 以外のクロスドメイン要求ヘッダーを許可する必要がある場合は、応答ヘッダーに Access-Control-Allow-Headers フィールドを追加して、許可される要求ヘッダーのリストを指定できます。例えば:
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
```
(5) Cookie を使用したリクエストなど、認証情報を含むリクエストを使用する場合は、応答ヘッダーに Access-Control-Allow-Credentials フィールドを追加し、認証情報の取得が許可されていることを示す true に設定する必要があります。送信されました。例えば:
response.setHeader("Access-Control-Allow-Credentials", "true");
```
最后,需要将这些响应头添加到每个需要跨域访问的 API 的响应中。
6. 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;
}
}
Cookie を使用したリクエストなど、認証情報を含むリクエストを使用する場合は、Access-Control-Allow-Credentials フィールドを true に設定する必要があります。これは、認証情報の送信が許可されることを意味します。例えば:
add_header 'Access-Control-Allow-Credentials' 'true';
Nginx の上流でロードバランシングを使用する場合、ロードバランシングのサーバーブロックに上記の設定を追加する必要があります。リバースプロキシを使用する場合は、リバースプロキシのサーバーブロックにも上記の設定を追加する必要があります。
7. ゲートウェイルーティングの構成
- id: my_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{
segment}
- AddResponseHeader=Access-Control-Allow-Origin:http://example.com
- AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
- AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
- AddResponseHeader=Access-Control-Allow-Credentials:true
`````
这将允许来自 http://example.com 的跨域请求访问 Gateway 中的 API。
Cookie を使用したリクエストなど、認証情報を含むリクエストを使用する場合は、Access-Control-Allow-Credentials フィールドを true に設定する必要があります。これは、認証情報の送信が許可されることを意味します。例えば:
- AddResponseHeader=Access-Control-Allow-Credentials:true
`````
最后,需要将这些配置添加到每个需要跨域访问的 API 的路由配置中。
需要注意的是,如果在 Gateway 的路由中使用了负载均衡,需要在负载均衡的路由配置中添加以上配置。如果使用了反向代理,也需要在反向代理的路由配置中添加以上配置。