在表单 onsubmit 上使用 JavaScript 后,Net Core RedirectAction 不起作用

Net Core RedirectAction not working after using JavaScript on form onsubmit

提问人:Ceased 提问时间:11/15/2023 最后编辑:Heretic MonkeyCeased 更新时间:11/16/2023 访问量:37

问:

我正在使用 JavaScript 在我的表单上提交。 它在后端很好地传递了数据,但是之后我的控制器上的重定向操作似乎不起作用

async function submitForm(event) {
    event.preventDefault();
    var form = document.getElementById('createAccountForm');
    var password = document.getElementById('user_password_input').value;
    if (!password) {
        var pworderrmsg = document.getElementById('pworderrormsg');
        pworderrmsg.textContent = "Please Enter a Valid Password!";
        pworderrmsg.style.display = 'block';
        return; // Form will not be submitted
    }
    //get the anti-forgery token
    // Retrieve the anti-forgery token value from the hidden input field
    var antiForgeryToken = document.querySelector('input[name="__RequestVerificationToken"]').value;

    // Make a POST request to your .NET Core API
    var options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'RequestVerificationToken': antiForgeryToken // Include the anti-forgery token in the headers
        },
        body: JSON.stringify({
            username_or_email: document.getElementById('user_email_input').value,
            Password: password
        })
    };
    await fetch('/auth/createaccount',options )
        .then(response => {
            if (!response.ok) {
                console.log(response);
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            return response.text();
        })
        .then(data => {
            alert(data.message);
            // Optionally, redirect or perform other actions upon successful account creation
        })
        .catch(error => {
            console.error('Error:', error.message);
            // Display a user-friendly error message or handle the error scenario appropriately
        });
}

然后在我的控制器上,我尝试重定向到一个随机页面,只是为了测试一下

return RedirectToAction("Index", "Home");

什么也没发生。

这是我的表格

<form id="createAccountForm" onsubmit="return submitForm(event)">
                                    @Html.AntiForgeryToken()
                //other stuffs
</form>
JavaScript C# ASP.net-核心-MVC

评论

0赞 Qiang Fu 11/21/2023
我认为您应该在提交后使用 javascript 重定向。

答:

0赞 Mohammad Sadegh Mazaheri 11/15/2023 #1

这里的问题可能是由于 JavaScript 获取请求的异步性质造成的。调用时 return RedirectToAction(“Index”, “Home”);在控制器中,表单将提交,重定向操作将在提取请求有机会完成之前执行。这会导致浏览器重定向到新页面,然后提取请求才有机会在成功创建帐户后显示成功消息或执行任何其他操作。

要解决此问题,您需要修改 JavaScript 代码以处理来自提取请求的响应,并在处理响应后执行重定向。以下是执行此操作的方法:

async function submitForm(event) {
event.preventDefault();
var form = document.getElementById('createAccountForm');
var password = document.getElementById('user_password_input').value;
if (!password) {
    var pworderrmsg = document.getElementById('pworderrormsg');
    pworderrmsg.textContent = "Please Enter a Valid Password!";
    pworderrmsg.style.display = 'block';
    return; // Form will not be submitted
}
//get the anti-forgery token
// Retrieve the anti-forgery token value from the hidden input field
var antiForgeryToken = document.querySelector('input[name="__RequestVerificationToken"]').value;

// Make a POST request to your .NET Core API
var options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'RequestVerificationToken': antiForgeryToken // Include the anti-forgery token in the headers
    },
    body: JSON.stringify({
        username_or_email: document.getElementById('user_email_input').value,
        Password: password
    })
};

try {
    const response = await fetch('/auth/createaccount', options);
    if (!response.ok) {
        console.log(response);
        throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    alert(data.message);
    // If the server has returned a success message, redirect to the desired page
    if (data.success) {
        window.location.href = "/some/redirect/url";
    }
} catch (error) {
    console.error('Error:', error.message);
    // Display a user-friendly error message or handle the error scenario appropriately
}

}

修改后的代码将等待提取请求完成,然后再执行重定向。这可确保在将用户重定向到新页面之前显示成功消息或错误消息。

根据评论进行更新

是的,您可以从控制器执行重定向,但您需要返回 JSON 响应,而不是直接重定向到视图。然后,JavaScript 代码将处理 JSON 响应,并使用 window.location.href 属性执行重定向。

下面是更新后的控制器代码:

[HttpPost]
public async Task<IActionResult> CreateAccount(CreateUserAccountViewModel model)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Perform account creation logic here
    // ...

    // Return a JSON response indicating successful account creation
    return Json(new { message = "Account created successfully!" });
}

在 JavaScript 代码中,修改 submitForm 函数以处理 JSON 响应并相应地重定向:

async function submitForm(event) {
event.preventDefault();

var form = document.getElementById('createAccountForm');
var password = document.getElementById('user_password_input').value;

if (!password) {
    var pworderrmsg = document.getElementById('pworderrormsg');
    pworderrmsg.textContent = "Please Enter a Valid Password!";
    pworderrmsg.style.display = 'block';
    return; // Form will not be submitted
}

// Get the anti-forgery token
var antiForgeryToken = document.querySelector('input[name="__RequestVerificationToken"]').value;

// Make a POST request to your .NET Core API
var options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'RequestVerificationToken': antiForgeryToken // Include the anti-forgery token in the headers
    },
    body: JSON.stringify({
        username_or_email: document.getElementById('user_email_input').value,
        Password: password
    })
};

try {
    const response = await fetch('/auth/createaccount', options);

    if (!response.ok) {
        console.log(response);
        throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const data = await response.json();
    alert(data.message);

    // Handle the JSON response and redirect accordingly
    if (data.success) {
        window.location.href = '@Url.Action("Index", "Home")'; // Replace with your actual redirect URL
    } else {
        console.error('Account creation failed!');
        // Handle error scenario appropriately
    }
} catch (error) {
    console.error('Error:', error.message);
    // Display a user-friendly error message or handle the error scenario appropriately
}

}

这种方法允许您将重定向逻辑集中在控制器中,同时仍保持 JavaScript 提取请求的异步性质。

评论

0赞 Ceased 11/15/2023
您好,感谢您的回答。有没有办法在控制器上进行重定向?
0赞 Mohammad Sadegh Mazaheri 11/16/2023
@Ceased 是的,您可以从控制器执行重定向,但您需要返回 JSON 响应,而不是直接重定向到视图。然后,JavaScript 代码将处理 JSON 响应,并使用 window.location.href 属性执行重定向。我在更新的答案中解释它。祝你好运
0赞 Qiang Fu 11/29/2023 #2

fetch 方法返回重定向响应。您只需要重定向到此响应 URL。您可以尝试关注。
控制器

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Test()
        {
            return RedirectToAction("Privacy", "Home");
        }

        public IActionResult Privacy()
        {
            return View();
        }

索引.cshtml

<button onclick="call()">Fetch</button>
<script>
    async function call() {
        var response = await fetch('/home/test', {
            method: 'GET'
        }).catch(error => console.log('error', error));
        await console.log(response);
        window.location.href=response.url;
    }
</script>

测试
enter image description here