【Vue.js】fetchのリダイレクト対応の注意点

Laravel

Vue.jsというかJavascript共通の問題ですが、

fetch()を使ってリダイレクトにfollowさせる際の注意点の備忘録です。

axiosでの挙動は確認していません。

そもそも、Javascriptの仕様であり、「問題点」ではありません。

レスポンス内容を気にしなければ、

CRUD処理でGETメソッドでリダイレクトさせるのは、

POSTメソッドのリクエスト処理後だけで良いと思います。

覚えておきたいHTTPメソッド/ステータスコード

POST後にリダイレクトさせる目的は、

多重送信によって新規レコードの多重作成を防止することにあります。

DETETE→削除されているので多重送信でもよくね?

PATCH→多重更新かけても最終結果は変わらなくね?

PUTも更新ならPATCHと同じじゃね?

とは言っても、その多重送信自体を極力避けたい場合や、

DELETEやPUT、PATCHのレスポンスの内容を受け取って処理をしたい場合、

GETメソッドでリダイレクトさせるケースはあっても良いと思います。

        return [ 'destroyed' => $post->delete() ];

のように、削除したレコード件数を結果として返し、

クライアント側で受け取りたいケースが考えられます。

fetch(
    url,
    {
        method: 'DELETE',
        redirect: follow,
        // other options...
    }
)

のような処理でAPIへアクセスして、

API側からリダイレクトのレスポンスが返ってきた際に、

fetch() はDELETEメソッドのままでリダイレクト先にアクセスします。

これは、PUT、PATCHについても同様です。

API側でGETメソッドのみのルーティングが行われていると

エラーとなってしまいます。

API側でリダイレクト時のレスポンスコードを303にすることで解決します。

Laravelの場合、

▼コントローラー

    public function destroy(int $id)
    {
        // ...
        return redirect(route('api.posts.destroyed'), 303)
            ->with('destroyed', $post->delete());
    }

    public function destroyed()
    {
        return [ 'destroyed' => session()->pull('destroyed') ];
    }

▼route/api.php

Route::prefix('/posts')->name('posts.')->group(function () {
    // ...
    Route::delete('/destroy/{id}', [PostsController::class, 'destroy'])->whereNumber('id')->name('destroy');
    Route::get('/destroyed', [PostsController::class, 'destroyed'])->name('destroyed');
    // ...
})->middleware('auth:sanctum');

のような感じでしょうか。

参考サイト

コメント

タイトルとURLをコピーしました