Vue.jsでSPA - [9] 今更ながらCORSとそのエラーの回避方法

[前回](https://qiita.com/narutaro/items/3b7135eed8f6e930a0e6)の続き


##前置き

CORSに関する記事はたくさんあるが、個人的に説明がいまいちわかりにくいなと思えたのでこれを書くことにした。個人的にわかりにくいと思った理由は以下：

1. ユースケースが適切な図で書かれてない
2. サーバ側、クライアント側という言葉で説明が書かれているが、Cross Originというくらいなので、オリジン（サーバ）は複数あり、その区別がつけにくい
3. なんの為にCORSの仕様があるのかの説明が不適切



## 何を読めばいいか

私にはこのページ [異なるドメインのURLからデータを参照する方法](http://koiroha.blogspot.com/2014/09/cross-origin-resource-sharing.html) がわかりやすかった。また、ここではCORS目的についても以下のように書かれている。

> クロスオリジンはしばしば「悪意のあるスクリプトが意図しないサイトに裏で勝手に情報を送ることを防止するため」と誤解した説明がされています。しかし送信側のスクリプトと受信側のサーバの両方が攻撃者の配下であれば CORS に対応させ裏で情報を送らせることは容易です。ユーザを守るものではなくコンテンツ提供側を守る仕組みです。

なるほど。



## CORSっているん？

いろいろ読んで、どう動くかはわかった。が、正直CORSを禁止するために各ブラウザ（user-agent）側でなんとかしようとしていることの意味はよくわかない。コンテンツ提供側を守ろうとした時に、ブラウザにそれを禁止する仕組みを入れることに意味があるのだろうか？どうせ `curl` やなんかなら普通に情報とれるんだからそのとった情報をあとはなんとでもできる。本当にCross Originでアクセスしてほしくないのなら、どうせコンテンツ提供側でも認証なりで守るんだろうから、ブラウザ側でなんとかする意味はなんなんだろうか....まあいいか。



## CORSのエラー



### Chrome

https://www.google.co.jp から https://your-url-one/ のリソース（API）を参照しようとした

```
Failed to load https://your-url-one/: Redirect from 'https://your-url-one/' to 'https://your-url-two' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.google.co.jp' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The FetchEvent for "https://your-url-one/" resulted in a network error response: the promise was rejected.
```



###Safari

https://www.youtube.com から https://your-url-one/ のリソース（API）を参照しようとした

```
[Error] Cross-origin redirection to https://your-url-two denied by Cross-Origin Resource Sharing policy: Origin https://www.youtube.com is not allowed by Access-Control-Allow-Origin.
[Error] Failed to load resource: Cross-origin redirection to https://your-url-two denied by Cross-Origin Resource Sharing policy: Origin https://www.youtube.com is not allowed by Access-Control-Allow-Origin. (your-url-one, line 0)
[Error] XMLHttpRequest cannot load https://your-url-two due to access control checks.
```



### 証明書のエラー（Chrome）

Chromeの場合は証明書のチェックが先に動くので、オレオレ証明書だったりするとCORSのエラーの前に `net::ERR_CERT_COMMON_NAME_INVALID` がでるはず



##やりたかったことを思い出して、エラーを回避する

このあたりで、SPA開発がしたかったんだと思い出して、エラーの回避方法を。



###Chrome

証明書のエラーは以下のようにオプション付きでChromeを立ち上げることで回避

```
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --ignore-certificate-errors &> /dev/null
```

ただ、CORSのエラーは残る。調べると `--disable-web-security` というフラグをつけることで回避できるとの情報があるがこれは古くてもう動かない様子。このフラグ付きで起動すると、ブラウザ上に`you are using unsupported command line flag --disable web security` と表示され，実際にCORSなAPIコールしたらエラーがでる．Chromeは詰んだか....




### Safari

SafariはGUIからCORSのチェックを外すことができる。[開発メニューを表示して](https://pc-karuma.net/safari-menu-development/)おいて開発メニューからCORSを無効化できる。


## 次回

ということで、CORSやる上で、Chromeはチェック厳しいので、開発にはSafariつかって進めていくことにしよう

## シリーズ

- [Vue.jsでSPA - [1] Element UIでベースの画面をつくる](https://qiita.com/narutaro/items/50d0e4714f93279502c9)
- [Vue.jsでSPA - [2] Element UIで各ペインの画面をつくる](https://qiita.com/narutaro/items/9abbf7881f692c985484)
- [Vue.jsでSPA - [3] vue-routerでルーティング ](https://qiita.com/narutaro/items/74178f4ea031b0ccfa44)
- [Vue.jsでSPA - [4] コンポーネントにしてみる ](https://qiita.com/narutaro/items/df793bb34129d113d9f2)
- [Vue.jsでSPA - [5] リアクティブになってる？](https://qiita.com/narutaro/items/bed4eab6e53e3b46c0b2)
- [Vue.jsでSPA - [6] サーバからのデータ取得](https://qiita.com/narutaro/items/82f4d9635c398524431c)
- [Vue.jsでSPA - [7] Vueからサーバデータ取得](https://qiita.com/narutaro/items/91da194788318c226e0e)
- [Vue.jsでSPA - [8] バックエンドとうまくやっていこうとして試したこと](https://qiita.com/narutaro/items/3b7135eed8f6e930a0e6)
- [Vue.jsでSPA - [9] 今更ながらCORSとそのエラーの回避方法](https://qiita.com/narutaro/items/26e4cbec386bc054bbd7)
- [Vue.jsでSPA - [10] Safari..お前か...3rd party cookie](https://qiita.com/narutaro/items/e53f653d73a6934046d0)
- [Vue.jsでSPA - [11] Element UIでログイン画面](https://qiita.com/narutaro/items/010009c0198371fee658)
- [Vue.jsでSPA - [12] ログイン：シングルペインからツーペインへ画面遷移](https://qiita.com/narutaro/items/fca953b3b2ed5c63360c)
- [Vue.jsでSPA - [13] モバイル向けに OnsenUI に手をだす](https://qiita.com/narutaro/items/bdc0e25c22369466bed3)
- [Vue.jsでSPA - [14] Vue.jsとOnsenUIを使ったオレオレなショッピングカートチュートリアル](https://qiita.com/narutaro/items/9502b90b565366911c57)
- [Vue.jsでSPA - [15] 世界中の人とミーティング時間を決める時に便利なやつ](https://qiita.com/narutaro/items/d6431f54050504bf1551)
- [Vue.jsでSPA - [16] へー、FirebaseでWebアプリのログインってこうやるのか](https://qiita.com/narutaro/items/3c37fe6c3b19a6143a07)




## （余談）ヘッダをいじってみる

CORSに必要なヘッダを簡単に試してブラウザの挙動を確認するには、リソース提供元のAPIサーバにこれ [WEBrickでCORS](https://qiita.com/oharato/items/7f20c74f63f70cc50bb2) を使うと良さそう。HTTPのやりとりはこんなかんじ

```yaml
Summary
URL: http://192.168.0.10:3000/
Status: 200 OK
Source: Network
Address: 192.168.0.10:3000

Request
GET / HTTP/1.1
Accept-Encoding: gzip, deflate
Host: 192.168.0.10:3000
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15
Accept-Language: en-us

Response
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 630
Date: Tue, 11 Sep 2018 23:07:36 GMT
Connection: Keep-Alive
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-11-22)
Access-Control-Allow-Origin: *
```

`Access-Control-Allow-Origin: *` が帰ってきているのが確認できる