-
-
Notifications
You must be signed in to change notification settings - Fork 705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
It's not possible to redirect in a server function if the request comes from a plain HTML form #3298
Comments
Here's my attempt to reproduce the behavior you describe use leptos::prelude::*;
pub fn shell(options: LeptosOptions) -> impl IntoView {
view! {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</head>
<body>
<App/>
</body>
</html>
}
}
#[server]
pub async fn redirect_me() -> Result<(), ServerFnError> {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
leptos_axum::redirect("/foo");
Ok(())
}
#[component]
pub fn App() -> impl IntoView {
let action = ServerAction::<RedirectMe>::new();
view! {
<ActionForm action>
<input type="submit"/>
</ActionForm>
}
} Due to the lack of hydration scripts there, this behaves as a plain old multi-page app and sends a regular form request. This does, in fact, return a 302 response with So it seems that the reproduction requires something more specific than the steps you wrote above. Could you please provide a small, self-contained example that reproduces the problem? Thanks. |
So, I've been struggling a lot to produce an example. First, I tried doing it in a project using 0.6, with the leptos/integrations/actix/src/lib.rs Lines 251 to 262 in 1ca279a
(I did not know that existed) Then I moved on to try to reproduce it on 0.7, which is where I discovered the problem in the first place. It seemed promising, given that the new code tries to do the same thing that is already done in leptos/integrations/actix/src/lib.rs Lines 378 to 391 in 5947aa2
Lines 273 to 292 in 5947aa2
Furthermore, the However, when I ran the application, instead of confirming the bug I have been seeing in my real application all along, I saw my browser displaying an error and refusing to show anything. Resending the request in cURL, I could see that there were two That makes total sense, since leptos/integrations/actix/src/lib.rs Lines 393 to 395 in 5947aa2
leptos/integrations/actix/src/lib.rs Lines 171 to 183 in 5947aa2
So I came back to my real application to try to understand why it doesn't send two Actually I had an epiphany writing this and realized that it was NGINX that was doing it. So the problem really is that both headers are being sent, not one overwriting the other. Having said that, I made a repo at https://github.com/veigaribo/leptos-server-fn-redirect-bug. |
Any interest in making a PR, based on what you've discovered, such that it inserts the |
I can give it a shot. |
Yes specifically this: for (key, value) in std::mem::take(&mut res_options.headers) {
headers.append(key, value);
} could be special-cased to check whether it's |
Closing since the discussed PR has been merged |
I'm trying to be as thorough as possible, so sorry if there's a mistake somewhere.
Also I'm not sure I would consider this a bug, or rather a limitation caused by the
server_fn
error-handling abstraction that is there by design, but recent discussions in the Discord server have led me to think of it as the former.Describe the bug
When a server function is invoked through a plain HTML form, presumably because JS and/or WASM is not being used, the following line of code will set the HTTP status code and the
Location
HTTP header of the response to some values, to allow for server-side rendering of errors (AFAIK):leptos/server_fn/src/lib.rs
Line 291 in 5947aa2
But, as a consequence, it is not possible to make the server function redirect anywhere else, since the above will end up overwriting the HTTP response in the end.
To Reproduce
Steps to reproduce the behavior:
leptos_actix::redirect
orleptos_axum::redirect
;ActionForm
with aServerAction
;Location
header of the response is the originating URL, not what you set (presumably your browser will allow you to do that);Location
header is correct.Expected behavior
I think the
Location
response header, as well as the status code, should end up being set to the values that were set in the server function, but I don't know how that would be the case while preserving the current behavior.Additional context
I was originally hoping that the
form-redirects
feature could be turned off fromleptos
entirely, so that I could sidestep this problem by not enabling the default features; but, if this really is a bug, then there must be a better solution. Allowing disabling ofform-redirects
would have its problems too.I am also a proponent of the idea that server functions should be distinct from server requests & responses, i.e. I believe server functions should just do the work and have a function-invocation interface, and there would be another entity that defines how a given function should be interacted with HTTP-wise. In that paradigm, the current
form-redirects
behavior could just be part of the default HTTP API of a server function, but it would be possible to be overwritten if desired.To be clear, I'm not asking for that to be implemented at all. If I had the time, I would (try to) do it myself in a different crate. Just mentioning it as food for thought.
The text was updated successfully, but these errors were encountered: