Laravel 自定義登入註冊頁面並使用 Ajax 進行資料傳輸

gapcold發表於2020-06-30

版本Laravel 7

自定義登入註冊頁面

直接修改resources/views/auth下面的login.blade.php和register.blade.php是最簡單的方法。
但是前端給的註冊登入是合併在一個頁面內的,當然可以複製兩份按照上面的步驟,但是考慮到日後維護,我想讓註冊和登入都指向同一個檢視,以後修改就不用同時修改兩份。
琢磨良久。
註冊頁面:
vendor/laravel/ui/auth-backend/RegistersUsers.php

public function showRegistrationForm()
{
    return view('auth.register');
}

修改view函式的引數即可。
登入頁面:
vendor/laravel/ui/auth-backend/AuthenticatesUsers.php

public function showLoginForm()
{
    return view('auth');
}

修改view函式的引數即可。

直接修改vendor資料夾內的內容當然不是最好的辦法,但我琢磨出來的辦法就只有這個。

使用Ajax註冊

這裡只說註冊,登入同理
csrf_token處理
由於laravel自帶反csrf攻擊,所以我們在post的時候應該傳遞我們頁面的token值,通過csrf_token()函式獲取。可作為表單資料傳遞(name:”_toekn”),也可以寫入請求頭。

headers: {
    'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
},

如何接收並展示後臺返回的錯誤資訊
返回錯誤資訊都是在驗證階段返回的,當用ajax時,驗證器會返回json資料,我們只要接收資料就可以了。

驗證器返回的json結構

{
    "message":"The given data was invalid.",
    "errors":{}
}

errors陣列內是具體的錯誤,並且已經經過語言檔案轉換。

我們只需要輸出errors中所有的錯誤給使用者看就可以了

var res = jQuery.parseJSON(xhr.responseText);
$("#err").html("");
for(var key in res.errors){
    $("#err").html($("#err").html()+res.errors[key]+"<br>")
}

註冊成功如何跳轉
laravel註冊成功後並不返回json,所以在我們指定datatype:'json'時,就算後端註冊成功,我們也無法進入success,所以我們需要在error中繼續判斷後端成功註冊的情況。
通過呼叫F12檢視控制檯XHR記錄,可以看到當註冊成功時,返回的HTTP狀態碼為201,所以我們只需要判斷狀態碼是否為201即可。

if(xhr.status==201){
    window.location.reload();
}

重新整理頁面後,由於是已經登入的狀態,會自動重定向到home頁面。

另外

  1. 頁面過期時(即token值不匹配),後端返回419狀態碼。
  2. 已經登入時,後端返回200狀態碼。

完整Ajax程式碼

$("#regbtn").click(function(){
    var name = $("#regname").val()
    var email = $("#regemail").val()
    var pwd = $("#regpassword").val()
    var cfpwd = $("#password-confirm").val()
    var flag
    $("#err").html("loading..");
    if(pwd!=cfpwd){
        $("#err").html("兩次輸入的密碼不一致!");
        return false;
    }
    $.ajax({
        type: 'POST',
        url: '{{route('register')}}',
        data: {"password_confirmation" : cfpwd, "password" : pwd, "email" : email, "name" : name, "_token" : "{{csrf_token()}}"},
        dataType: 'json',
        headers: {
            'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
        },
        success: function(data){
            window.location.replace("{{route('home')}}")
        },
        error: function(xhr, type, errorthrown){
            if(xhr.status==419)
                $("#err").html("頁面過期!請重新整理頁面");
            else if(xhr.status==201){
                window.location.reload();
            }
            else if(xhr.status==200){
                window.location.reload();
            }
            else{
                var res = jQuery.parseJSON(xhr.responseText);
                $("#err").html("");
                for(var key in res.errors){
                    $("#err").html($("#err").html()+res.errors[key]+"<br>")
                }
            }
        }
    });
});

在Laravel中體會到了物件導向程式設計的小小弊端,就是不斷找父類找到吐。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章