【ajax】"CORSポリシーによってブロックされています" によりデータが取得できない

# １．実現したいこと

jQuery + Ajax で YouTube Data APIを使用し、特定のキーワードで検索を行い、動画のサムネイル、タイトル、URLを取得したい。
そのためにボタンを押した際、下記コードでサーバーにリクエストを送信した。

```javascript:main.js
$button.on("click", function () {
    let url = "https://www.googleapis.com/youtube/v3/search";
    url += "?key=" + KEY;
    url += "&part=snippet";
    url += "&type=video";
    url += "&q=%20筋トレ%20ジム" + $(this).data("parts");
    url += "&maxResults=6";
    $.ajax({
      url: url,
      type: "GET",
      dataType: "json",
    })
      .done(function (data) {
        for (let i = 0; i < data.items.length; i++) {
          let html = `
          <li>
            <a href="https://www.youtube.com/watch?v=${data.items[i].id.videoId}" target="_blank">
              <dl>
                <dt>
                  <img src="${data.items[i].snippet.thumbnails.high.url}">
                </dt>
                <dd>${data.items[i].snippet.title}</dd>
              </dl>
            </a>
          </li>
          `;
          $mov_blk.append(html);
        }
      })
      .fail(function () {
        $mov_blk.html('<li class="no_video">検索結果はありません</li>')
      });
  });
```

# ２．エラー内容

>Access to XMLHttpRequest'リクエストを送ったURL' is blocked by CORS policy: No'Access-Control- The Allow-Origin header is present in the requested resource.

**【日本語訳】**
URLはCORSポリシーによってブロックされています：いいえ' Access-Control-Allow- Originのヘッダーはリクエストされたリソースに存在します。

# **３．調査**

以下のワードでググる
- Access-Control-Allow-Origin ajax
- CORSポリシーによってブロック

# **４．原因**

クロスドメインに引っかかりエラーが出ていた。
CORSという制約により、やり取りする間で特別な取り決めが無い限り、すべてのサーバーと自由にやり取りをできるわけではない（同じドメイン以外は通信不可）

参考：[クロスドメイン](https://otiai10.hatenablog.com/entry/2013/04/04/233057)、[CORS](https://javascript.keicode.com/newjs/what-is-cors.php)

# **５．解決策**

`dataType: "jsonp"`に変更。

```javascript:main.js
$button.on("click", function () {
    let url = "https://www.googleapis.com/youtube/v3/search";
    url += "?key=" + KEY;
    url += "&part=snippet";
    url += "&type=video";
    url += "&q=%20筋トレ%20ジム" + $(this).data("parts");
    url += "&maxResults=6";
    $.ajax({
      url: url,
      type: "GET",
      dataType: "jsonp", //jsonpに変更
    })
      .done(function (data) {
        for (let i = 0; i < data.items.length; i++) {
          let html = `
          <li>
            <a href="https://www.youtube.com/watch?v=${data.items[i].id.videoId}" target="_blank">
              <dl>
                <dt>
                  <img src="${data.items[i].snippet.thumbnails.high.url}">
                </dt>
                <dd>${data.items[i].snippet.title}</dd>
              </dl>
            </a>
          </li>
          `;
          $mov_blk.append(html);
        }
      })
      .fail(function () {
        $mov_blk.html('<li class="no_video">検索結果はありません</li>')
      });
  });
```

▼JSONPとは
異なるドメインに存在するデータを取得する仕組みのこと。

JSONPは危険という記事もあったので、実用であれば **”Access-Control-Allow-Origin”** をPHPや.htaccessで設定した方が安全かもしれません。

参考：[JSONPは危険なので禁止](https://blog.ohgaki.net/stop-using-jsonp#i)

# **６．参考資料**

- [Ajaxにおけるクロスドメインの問題を回避する方法](https://www.bloguchi.info/1679)
- [CORS とは？](https://javascript.keicode.com/newjs/what-is-cors.php)
- [4ステップで作って学ぶJSONP](https://zenn.dev/bun913/articles/0c807fa8da262e)
- [JSONPは危険なので禁止](https://blog.ohgaki.net/stop-using-jsonp#i)