blog

クロスドメインの問題と解決策をフロントエンドとバックエンドに分けて開発する

会社の開発モデルはフロントエンドとバックエンドが分離されていないため、実際の開発では基本的にクロスドメインリクエストの問題に遭遇しませんでしたが、関連する問題にも注意を払っていませんでした。 1.フロ...

Mar 24, 2020 · 4 min. read
シェア

領域横断的な問題とソリューションの開発におけるフロントエンドとバックエンドの分離

会社の開発モデルはフロントエンドとバックエンドに分かれていないため、実際の開発では、基本的にクロスドメイン要求の問題に遭遇しなかっただけでなく、関連する問題にも注意を払っていませんでした。

問題の記述

フロントエンドとバックエンドの分離の開発では、フロントエンドのページ要求のバックエンドのインターフェイスは、クロスドメインエラーの出現に制御するときがありますが、インターフェイスだけのテストは問題ではありません!

解決方法

フロントエンド処理
  1. サービスコール時のクロスドメイン処理
  • 通常の状況でajaxを使用してサービスを呼び出す場合

$("#demo1").click(function(){
 $.ajax({
 url : 'http://..top/Index/Test/crossDomain',
 data : {},
 type : 'get',
 success : function (res) {
 //No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://...1' is therefore not allowed access. 実行中に報告されたエラーはクロスドメインエラーを表す。
 alert(res);
 }
 });
});
  • インターフェイスの呼び出しにjsonpを使用しますが、この方法はGETリクエストに限られており、制約が多すぎます。

$("#demo2").click(function(){
 $.ajax({
 url : 'http://..top/Index/Test/crossDomain',
 data : {},
 type : 'get',
 dataType : 'jsonp', 
 success : function (res) {
 alert(res);
 }
 });
});
  1. リバースプロキシによるクロスドメイン問題の処理

vue-cliプロジェクトの場合、プロジェクトのルートディレクトリにグローバル設定ファイルvue.config.jsを作成します。

module.exports = {
 // 基本パス
 publicPath:"./", // を相対パスに設定することで、すべてのリソースが相対パスにリンクされ、パッケージを任意のパスにデプロイすることができる。
 outputDir:"dist", //パッケージング時に生成される本番環境ビルドファイルのディレクトリ
 assetsDir: 'public', // 生成された静的リソースを置くディレクトリ
 devServer: {
 //プロキシモード。インターフェイスのクロスドメイン問題を解決するために使われる
 proxy: {
 '/api': {
 //target: '"http://localhost:8100"/pm', // 自身のインターフェースに対応する
 target : '"http://...189:8100"/pm',
 changeOrigin: true,
 ws: true,
 pathRewrite: {
 '^/api': '',
 },
 },
 },
 }
}
バックエンド処理
  1. プロジェクトが SpringBoot の場合は、Controller クラスの jdk バージョン 1.8 以降に @CrossOrigin アノテーションを直接追加します。
/**
 クロスドメイン問題を解決するために、他のコントロールレイヤーはこのクラスを継承することができる。
*/
@CrossOrigin
public class commonController {
}
  1. インターセプター・アプローチによる実装
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
 @Autowired
 private EnvConfig envConfig;
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
 registry.addInterceptor(new HandlerInterceptor() {
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
 throws Exception {
 boolean isTrue = envConfig.getIsDev();//クロスドメインの問題を解決するだけのテストサービスであると判断する
 if (isTrue) {
 response.addHeader("Access-Control-Allow-Origin", "*");
           response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
 response.addHeader("Access-Control-Allow-Headers",
 "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");
 }
 return true;
 }
 @Override
 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
 ModelAndView modelAndView) throws Exception {
 }
 @Override
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
 Exception ex) throws Exception {
 }
 });
 }
}
  1. フィルターによる判断

@Configuration
public class GlobalCorsConfig {
 /**
 * フィルタへのクロスドメイン呼び出しを許可する
 */
 @Bean
 public CorsFilter corsFilter() {
 CorsConfiguration config = new CorsConfiguration();
 //すべてのドメインにクロスドメイン呼び出しを許可する
 config.addAllowedOrigin("*");
 //クッキーの送信を許可する
 config.setAllowCredentials(true);
 //すべての生ヘッダを解放する
 config.addAllowedHeader("*");
 //すべてのリクエストメソッドをドメインをまたいで呼び出せるようにする
 config.addAllowedMethod("*");
 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
 source.registerCorsConfiguration("/**", config);
 return new CorsFilter(source);
 }
}
  1. グローバルコンフィギュレーション用のグローバルコンフィギュレーター。
@Configuration
public class CorsMappingConfig implements WebMvcConfigurer {
 @Override
 public void addCorsMappings(CorsRegistry registry) {
 registry.addMapping("/dev/**")
 .allowCredentials(true)
 .allowedMethods("GET","PUT","DELETE","POST","OPTIONS")
 .maxAge(3600);
 }
}
Nginx介入方法

設定ファイルは次のとおりです。

server{
 listen 8888;
 server_name 192.0;
 # の静的ページ
 location /{
 proxy_pass "http://...100:8080";
 }
 # api 
 location /api{
 proxy_pass "http://localhost:8100"/api;
 }
 }
Read next

iOSタイマー比較とグローバルタイマーパッケージ

NSTimer、GCDタイマーを含むiOSの一般的に使用されるタイマー、。これは主に、グローバルタイマーのカプセル化と同様に、3種類のタイマーの使用を紹介します。 最初のこれは、循環参照につながるため、自己の強い参照タイマーは、タイマーの強い参照ターゲットは、タイマーのリリース失敗につながるでしょう。 第二この方法は、循環参照の問題を解決することができます...

Mar 24, 2020 · 5 min read