2014年1月23日木曜日

YQL と jsonpost で、POST メソッドを使うクロスドメイン JSON データを取得する

http の post メソッドを使ってクロスドメインの json を取得する必要が生じた。
yql に直接 post メソッドでリクエストすることはできないが、 Open Data Tables にある jsonpost を使えば可能である(このテーブルには htmlpost もあるようだ)。もちろん yql には get メソッドでリクエストするので長大なデータは送れない。
ちなみに yql が生成する http リクエストの Content-Type は application/x-www-form-urlencoded になっていた(ま、テーブルの定義に書いてあるとおりなんだけれど)。
以下コード断片。

var url = "http://foo.com/post.json";
var postdata = "post_data=" + encodeURIComponent("post_data value");
$.ajax({
    url: yql_make_url(url, "jsonpost", "json", postdata),
    dataType: "json",
    type: "GET",
    success: function(data){
        var json = data.query.results.postresult.json;
    }
});

function yql_make_url(url, from, to, postdata)
{
    if (! from)
        from = "html";
    if (! to)
        to = "xml";
    var q = 'select * from ' + from + ' where url="' + url + '"';
    var env;
    if (from == "jsonpost"){
        q += ' and postdata="' + postdata + '"';
        env = "store://datatables.org/alltableswithkeys";
    }
    var yql = "http://query.yahooapis.com/v1/public/yql?q=" + encodeURIComponent(q);
    yql += "&format=" + to;
    if (from == "json" || from == "jsonpost")
        yql += "&jsonCompat=new";
    if (env)
        yql += "&env=" + encodeURIComponent(env);
    return yql;
}