HTTP 重定向不呈现新页面
HTTP redirect not rendering new page
我让用户登陆登录页面。当他们成功登录时,这应该会将他们重定向到用户页面。然而,这并没有发生,我不确定为什么。似乎 ajax 调用由于某种原因进入错误(我不确定为什么)。不过,当我在响应文本中记录新页面的响应时,我可以看到。
应该重定向用户的登录方法:
// this map stores the users sessions. For larger scale applications, you can use a database or cache for this purpose
var sessions = map[string]session{}
// each session contains the username of the user and the time at which it expires
type session struct {
username string
expiry time.Time
}
// we'll use this method later to determine if the session has expired
func (s session) isExpired() bool {
return s.expiry.Before(time.Now())
}
// Credentials Create a struct that models the structure of a user in the request body
type Credentials struct {
Password string `json:"password"`
Username string `json:"username"`
}
func login(w http.ResponseWriter, r *http.Request) {
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
http.Redirect(w, r, "/users", http.StatusFound)
}
Ajax 调用:
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: '/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.redirect) {
// resp.redirect contains the string URL to redirect to
window.location.redirect = resp.redirect;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}
所以要解决你的问题,你应该稍微修改一下你的服务器代码
func login(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
by, _ := json.Marshal(map[string]interface{}{
"to": "http://localhost:8085/users",
})
w.Write(by)
}
我使用 json 响应而不是 http.redirect。
回到您的 ajax 调用,我再次将数据类型更改为 json,因为我们的服务器现在发送 json。将 if 条件从 resp.redirect 更改为 resp.to,并使用 window.location.href 而不是 windows.location.redirect。
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: 'http://localhost:8085/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.to) {
window.location.href = resp.to;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}
我让用户登陆登录页面。当他们成功登录时,这应该会将他们重定向到用户页面。然而,这并没有发生,我不确定为什么。似乎 ajax 调用由于某种原因进入错误(我不确定为什么)。不过,当我在响应文本中记录新页面的响应时,我可以看到。
应该重定向用户的登录方法:
// this map stores the users sessions. For larger scale applications, you can use a database or cache for this purpose
var sessions = map[string]session{}
// each session contains the username of the user and the time at which it expires
type session struct {
username string
expiry time.Time
}
// we'll use this method later to determine if the session has expired
func (s session) isExpired() bool {
return s.expiry.Before(time.Now())
}
// Credentials Create a struct that models the structure of a user in the request body
type Credentials struct {
Password string `json:"password"`
Username string `json:"username"`
}
func login(w http.ResponseWriter, r *http.Request) {
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
http.Redirect(w, r, "/users", http.StatusFound)
}
Ajax 调用:
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: '/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.redirect) {
// resp.redirect contains the string URL to redirect to
window.location.redirect = resp.redirect;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}
所以要解决你的问题,你应该稍微修改一下你的服务器代码
func login(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
log.Println("login started")
var creds Credentials
// Get the JSON body and decode into credentials
if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
// If the structure of the body is wrong, return an HTTP error
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
// Get the expected password from our in memory map
expectedPassword, ok := "test", true
// If a password exists for the given user
// AND, if it is the same as the password we received, then we can move ahead
// if NOT, then we return an "Unauthorized" status
if !ok || expectedPassword != creds.Password {
log.Println("bad password")
w.WriteHeader(http.StatusUnauthorized)
return
}
// Create a new random session token
// we use the "github.com/google/uuid" library to generate UUIDs
sessionToken := uuid.NewString()
expiresAt := time.Now().Add(120 * time.Second)
// Set the token in the session map, along with the session information
sessions[sessionToken] = session{
username: creds.Username,
expiry: expiresAt,
}
// Finally, we set the client cookie for "session_token" as the session token we just generated
// we also set an expiry time of 120 seconds
http.SetCookie(w, &http.Cookie{
Name: "session_token",
Value: sessionToken,
Expires: expiresAt,
})
log.Println("login success")
by, _ := json.Marshal(map[string]interface{}{
"to": "http://localhost:8085/users",
})
w.Write(by)
}
我使用 json 响应而不是 http.redirect。 回到您的 ajax 调用,我再次将数据类型更改为 json,因为我们的服务器现在发送 json。将 if 条件从 resp.redirect 更改为 resp.to,并使用 window.location.href 而不是 windows.location.redirect。
function handleSubmit(evt) {
evt.preventDefault();
let form = evt.target;
let data = new FormData(form);
if (data.get("username") != null && data.get("username") != "") {
$.ajax({
url: 'http://localhost:8085/login',
method: 'post',
data: JSON.stringify(Object.fromEntries(data)),
dataType: 'json',
success: (resp) => {
if (resp.to) {
window.location.href = resp.to;
}
},
error: (resp) => {
console.log("An error occurred. Please try again");
console.log(resp)
}
});
}
return false
}