Drafts

@cm3 の草稿置場 / 少々Wikiっぽく使っているので中身は適宜追記修正されます。

CORS に関するエラーが出たときに確認すること

要はマイクロサービス的な設計にしている場合など、APIだからって外部から使われることを前提にしていないことは多々あるので、CORS設定が「適切でない」と疑う前に、まずCORSを許そうとしているかを疑えってことだったのですが。それはともかく、「CORSの問題を疑いつつも自分がミスってないか色々確認して」という部分についてここに詳細を記しておく。また、他人様に「CORS許すつもりがないよ」ってエラーを渡してあげれば親切なので、その方法についても書く。

実際に実装してコンソールとかでチェック

どうせCORS以外の問題もチェックしなきゃいけないので実装はすればいい。すぐだし。一応三種類実装してみたけど、別にこれらによって挙動が異なることはなかったから fetch 使っておけばいいと思う。

オススメな方法

async function postData(url = '', data = {}) {
    const response = await fetch(url, {
      method: 'POST', // GET, POST, PUT, DELETE, など
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });
    return response.json();
}

postData('接続先', データオブジェクト)
    .then(data => {
       doSomething(data); //ここで何かする
    }).catch(error => {
        console.error('error!!!', error);
        });

jQueryを使う

function postDataJQ(url = '', data = {}) {
    $.ajax({
    type: 'postかgetか',
    url: '接続先',
    data: JSON.stringify(data),
    contentType: 'application/json',
    dataType: 'json',
    success: function(returnedData){doSomething(returnedData);}, //ここで何かする
    error: function(XMLHttpRequest, textStatus, errorThrown) {
           alert('error!!!');
      console.log("XMLHttpRequest : " + XMLHttpRequest.status);
      console.log("textStatus     : " + textStatus);
      console.log("errorThrown    : " + errorThrown.message);
    }
    });
}

postDataJQ('接続先', データオブジェクト);

バーニラバニラで高収入♪(vanilla javascriptでold style)

function postDataOld(url = '', data = {}) {
  var xhr = new XMLHttpRequest();
  xhr.open("POST", url);
  xhr.setRequestHeader("Content-Type", "application/json");
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      console.log(xhr.status);
      doSomething(xhr.responseText); //ここで何かする
  }};
  xhr.send(JSON.stringify(data));
}

postDataOld('接続先', データオブジェクト);

curl で確認する

Firebase で何かを POST しようとしたら CORS の preflight で怒られましたね? - Qiita に紹介されているように、

curl -H "Content-Type:application/json" -H "Origin: localhost:8080…のような送り元" -d '送るデータ' 送り先 -vvv

とか

curl -H "Origin: 127.0.0.1:8080" -H "Access-Control-Request-Method: POST" -X OPTIONS -vvv 送り先

を実行して、< access-control-allow-origin: * みたいなのが返ってきているか確かめる。ちなみに、頭の<が通信の方向を指し示していることに今更気づいたw 前者は実際の接続用であり、後者は preflight 用であり、接続がPOSTなら前者にも -X POST を指定すればよい。ちなみに日本語データとかはパーセントエンコーディング済みのものを渡せばいい

ちゃんとCORS許す気ないとかエラーで教えてあげられると親切

例えば cenobites/flask-jsonrpc: Basic JSON-RPC implementation for your Flask-powered sites とか使ってAPI実装しているなら、Add ability to return custom error numbers in reponse · Issue #38 · cenobites/flask-jsonrpc に書かれているように flask_jsonrpc.exceptions 使って、

from flask_jsonrpc.exceptions import Error

@jsonrpc.method('App.error')
def error():
    error = Error()
    error.data = {'info': 'Read https://blablabla for more info.'}
    raise error

とかしておくとよいのかもしれない。ちゃんとorigin見てドメイン外からの接続であることを確認してエラー吐いてとかやろうとすると面倒なので、一括でウェブサイトへのリンクだけ貼っておいて、詳細はドキュメンテーションで対処すればいいと思う。

その他