TableauWDCで CORSを回避する方法（超意訳）

https://tableau.github.io/webdataconnector/docs/wdc_cors

WDCをやっていると必ずと行っていいほど起きる問題が、CORS（cross-origin resource sharing）のようです。
それの対策について、まとまっていたので、つたないですが超意訳（？）してみます。

---

WDCではJavaScriptのコードで実装されていて、実際にこのコードが配置されるサーバ（ドメイン）とは別のWebサーバにAPIリクエストをして、データを取得する場合がほとんどと思います。
これはすなわちCORS（cross-origin resource sharing）と呼ばれるものですが、セキュリティ上、ブラウザはこのCORSを制限しています（特にChromeとか）
※WDCでは、Tableauの内部ブラウザを使っているので、CORSを回避するChromeのプラグインは利用できない・・・

CORS制限のために、ブラウザのコンソールに下記のようなエラーが出ると思います

```
XMLHttpRequest cannot load URL. No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

このエラーを回避するのにいくつかの方法があるのでそちらを説明します

- ローカルにプロキシを立てる（Make requests through a proxy server）
- 利用するAPIサーバにCORSを許可するようにお願いする（Request CORS support from API Server）
- JSONPをつかってAPIへリクエストを送る（Make requests with JSONP）

※注釈　[Debugging in the Simulator and Tableau) ](https://tableau.github.io/webdataconnector/docs/wdc_debugging) でデバッグの方法が書いてますが、その中にもCORSのエラーについては書いてあるっぽい

# ローカルにプロキシを立てる（Make requests through a proxy server）
ブラウザのCORS制限を回避するために、プロクシサーバを立てて、それを経由して、リクエストを送る方法があります。プロキシーは単純にデータを取得するだけの動きをします（データ加工などは一切しない）
このプロキシはブラウザで動くわけではないので、ブラウザのCORS制限には引っかからないのです

データの取得先のドメインが、WDCサーバと同じならCORS問題は起きませんが、別ドメインからのデータ取得だとCORS問題がおきます。
もしプロキシサーバのドメインが別なら、そのプロキシサーバで　`Access-Control-Allow-Origin` をヘッダにセットすれば動きます。

WDCSDK　には、そのまま使えるプロキシサーバが設定されています。

### webdataconnectorのリポジトリの第一階層で、下記のコマンドをTerminalなどで打ちます。 
```
npm start
```
これで、テストサーバとテストプロキシサーバが起動します

### プロキシは下記のURLになる
```
http://localhost:8889
```
例えば　`earthquakeUSGS`　のコネクタの場合, `$.getJSON` の記載は

```
$.getJSON("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson"
```

となってますが、こちらを

```
$.getJSON("http://localhost:8889/earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson"
```

と変更することで、プロクシ経由でCORS制限を回避してアクセスできます。
重要：　httpのみしか対応してない。
※httpsのAPIにアクセスする場合は、　[Tableau WDCの「Allow-Control-Allow-Origin: *」問題を回避してみる](https://qiita.com/tashiro_gaku/items/6aa91507df786fc12cb7)を参考にしてみてください。

フリーのプロキシ　にはこんなのがある（らしい）。こちらを使うのも手

- http://cors.io/
- https://crossorigin.me/

# 利用するAPIサーバにCORSを許可するようにお願いする
`Access-Control-Allow-Origin`　をヘッダにつけてもらうようにAPI提供先にお願いする
（それで解決できるならこれが一番だとは思うが！）


# JSONPを使う
CORS対策をしていないサーバでも、JSON with padding　もしくは　JSONP でデータが取得できる場合が多くあります。直接JavaScriptを使うとブロックされてていても、JSONPを使えば可能（？）
その代わりに、JavaScriptを使用して `<script>` 要素を動的に作成または更新し、`src`属性をデータを持つサイトを指すURLに設定します。URLには、コネクタページにあるコールバック関数の名前も含まれています。サイトがJSONPをサポートしている場合、レスポンスにはJSON形式のデータが含まれており、コールバック関数の呼び出しで「パディング」されます。

Webデータ・コネクターでjQueryを使用する場合は、ajax関数を使用してJSONP呼び出しを行うことができます。詳細は、jQueryサイトのjQuery.ajax（）を参照してください。


jQueryを使用していない場合は、JavaScriptコードでJSONPを実装できます。たとえば、コネクタに次のJavaScriptコードが含まれていると、`<script>`要素が動的に作成され、`src`属性が架空のURLに設定されます。

```javascript
var scriptTag = document.createElement('script');
scriptTag.src = "http://myserver/temperatures?city=Seattle&year=2014&callback=getTemperatures";
document.getElementsByTagName('head')[0].appendChild(scriptTag);
```


コネクタには、サイトが返す「埋め込まれた」JSONによって呼び出される次の関数も含まれている必要があります。 JSONデータはjsonpDataパラメータとして関数に渡され、関数内のコードはJSONブロックの場合と同じように値を抽出できます。

```javascript

var getTemperatures = function(jsonpData) {
        alert(jsonpData.someProperty);
        // More code here to extract the JSON data
    }
```

参考　

- [
これでできる！ クロスブラウザJavaScript入門 第11回　JSONP入門](http://gihyo.jp/dev/serial/01/crossbrowser-javascript/0011) 
- [JSONPをごりごり実装するときのポイント](https://qiita.com/stkdev/items/f3e6cae58ab73faee502)
- [jQueryでAjaxするときに知っておきたい、JSONとJSONPの違い](https://www.webprofessional.jp/jsonp-examples/)