雰囲気でCORSの設定してたので設定によってどんな結果になるか調べてみたよ。
クライアントとサーバのコード
クライアント
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script> $(document).ready(function () { $('#get').click(function () { axios.get('http://localhost:8080/hello') .then(function (response) { console.log('get', response.status, response.data); }); }) $('#post').click(function () { axios.post('http://localhost:8080/hello', { id: 1, text: 'hello' }) .then(function (response) { console.log('post', response.status) }) }) }); </script> </head> <body> <button id="get">GET</button> <button id="post">POST</button> </body> </html>
サーバ
- getとpostのリクエストを簡単に処理するだけのやつです
@RestController @RequestMapping("/hello") class HelloController { @GetMapping fun get(): String { return "hello" } @PostMapping fun post(@RequestBody body: Body) { println("body = ${body}") } data class Body( private val text: String ) }
何も設定を行わずにクライアントからリクエストを投げてみる
デフォルト状態で、異なるドメインからリクエスト投げるとこんな感じにエラーになりますね。
Controllerに@CrossOrigin
アノテーションを設定してみる
Controllerに対して、@CrossOrigin
アノテーションを設定すると、Controller毎に細かく設定ができます。
また、ハンドラメソッドに対して設定した場合には、より細かく設定できるようになります。
Controllerにアノテーションを設定した場合
Controllerクラスに@CrossOrigin
アノテーションを設定すると、このController内のハンドラメソッドがすべて許可されるようになります。
@CrossOrigin
のvalue(origins)
やallowedHeaders
を設定することで、より細かな設定もできるようになっています。
@RestController @RequestMapping("/hello") @CrossOrigin class HelloController { // 省略 }
実行結果
@CrossOrigin
アノテーションを設定したことで、ちゃんと異なるドメインからの要求が処理されるようになりました。
ハンドラメソッドにアノテーションを設定した場合
ハンドラメソッドに@CrossOrigin
アノテーションを設定すると、そのリクエストのみ許可されるようになります。
もし、Controllerにも設定されていた場合、Controllerとハンドラメソッドの設定がマージされる感じになります。
@RestController @RequestMapping("/hello") class HelloController { @GetMapping fun get(): String { return "hello" } @PostMapping @CrossOrigin fun post(@RequestBody body: Body) { println("body = ${body}") } data class Body( private val id: Int, private val text: String ) }
実行結果
今回は、POSTの処理だけに@CrossOrigin
アノテーションを設定したので、POST処理だけ成功しています。
WebMvcConfigurerを使って横断的に設定してみる
WebMvcConfigurer#addCorsMappings
を使うと、アプリケーション全体に対して設定を行うことができるようになります。
デフォルトでは、GET、HEAD、POSTしか許可されていないので、それ以外を許可する場合には allowedMethods
を設定して上げる必要があります。
設定は、こんな感じにWebMvcConfigurer
のBeanを登録してあげるだけですね。
@Configuration class WebConfig { @Bean fun config(): WebMvcConfigurer { return object: WebMvcConfigurer { override fun addCorsMappings(registry: CorsRegistry) { registry.addMapping("/**") .allowedOrigins("http://localhost:63342") .allowedMethods("GET", "POST", "PUT") } } } }
実行結果
個別のControllerに@CrossOrigin
アノテーションを設定しなくても処理が成功するようになりました。