Safariのajaxがfailに流れるという悲しい話

Safari

タイトル通りなのですが、この原因に気づかずにお客さんを困らせてしまっていたので反省のためのメモ。

環境はCakephp3になるのですが、Viewにて下記のように処理してました。

$.ajax({
    url: '<?=Router::url(['controller' => 'Hoge', 'action' => 'hoge'], true)?>',
    type: "post",
    beforeSend: function(xhr){
        xhr.setRequestHeader('X-CSRF-Token', csrf);
    },
    data: ajaxdata,
}).done(function (response) {
    try {
        console.log(response);
    } catch (e) {
        console.log(e);
    }
}).fail(function (jqXHR, textStatus, errorThrown) {
    console.log(jqXHR);
    console.log(textStatus);
    console.log(errorThrown);
});

IEでも、Chromeでも、FireFoxでも処理されているのに、なぜかSafariではfailになるという話です。

解決策としては

async: false,

を入れて完了です。

Safariではどうやら同期処理(asyncは非同期。それがfalseだから同期という意味)をしてやらないとfailになるようです。

この件で調べていると他に

・beforeSendでエージェントを判定して、リクエストヘッダにIf-Modified-Sinceで最新日時を渡すことで最新データであると認識させなきゃダメ

・cache:false をしないとダメ

・urlにhttp,httpsからではなく相対パスが良い

などありましたが有効ではありませんでした。

というよりもSafariのバージョンが14で確認しているため、これ以前では上記が有効な手段だったのかもしれません。

早くこういったブラウザ依存が消滅してほしいですね。

それでは、また