Comments (4)
There are several issues where this has been brought up over the last few months, see
The brief overview, for those not familiar is that the current implementation of server actions will attempt to decode the response body of any request that is not 400-599 status codes. This causes problems as the response bodies of 302 (and any other redirect) is the body of the redirected page (which is frequently HTML).
There is currently no way to get at the actual request body in major browsers so that alternative is to change the call signatures of the server function API.
I have several proposals that have varying levels of breaking change.
- Change the signature of call_server_fn to be
Result<MaybeRedirect<T>, ServerFnError>
whereMaybeRedirect<T>
requires the caller to check if the response body is a redirect. This is probably unreasonable, but it is a solution and at worst would introduce an unwrap() to get at the value of T.- Localize all of the client side networking code (Action Forms, Forms, Server Functions) into a single place with a create_request() API that gives the user the option to configure automatic client side navigation on 302. Something like
if let Ok(response) = create_request::<MyServerFn>().follow().fetch().await { // Your code here }
- Add a
ServerFnError::Redirect(RedirectResponse)
variant and introduce a navigate() helper onRedirectResponse
that makes it possible to hand this in userland.I'd like to hear feedback on some of these proposals, I personally think 2 with 3 are the most idiomatic way of handling this.
There is an easy way to get the actual response body in the browser, and that is to include the Accept header with the encoding you want (application/cbor
) for example in your Request. I am not sure why you'd want the body of a 302 redirect, other than to redirect, which we do for you.
The reason it works the way it does currently is that this is the only way form submission works without JS and Webassembly enabled, to provide graceful degradation.
We're working on a server fn rewrite for 0.6 that will change some of how this would be done, but probably not this behavior. Open to ideas that will preserve graceful degradation though
from leptos.
The issue isn't about getting the response body, its about handling the redirect.
Right now the only place that its handled is in the Form component in leptos_router. Where the action is proxied and if a 302 comes in the header of the response it will navigate on the client.
This is great, but lets say for instance that you have an action behind a guard where failure to authenticate redirects you to /signin. This action wouldn't be called from a form because its returning a list of items to display to the user. If I call leptos_axum::redirect("/signin") after failure to authenticate it will redirect during SSR, but it won't redirect during client side rendering.
This is a shortcoming of putting 302 header handling inside of a component where the whole action handling is re-implemented for a specific use case.
from leptos.
There are two separate issues here I think:
redirect()
can't work with normal server fn calls Server functions are written in a framework-agnostic way and therefore don't know anything about client-side routing, which is very framework dependent. We are rewriting the whole server function package at the moment, and it would be possible to introduce what's essentially a router hook: if the response is a redirect, the server fn will call that router hook with theLocation
header. Then, the Leptos-specific wrapper for agnostic server functions can provide a router hook that navigates to that.- Browser behavior around 302s This is the "trying to decode HTML as server fn return data" issue. We can't change the browser behavior here, of course. We could decide to bypass it entirely, and use a separate redirect system rather than 302 +
Location
. For example, we could decide thatredirect()
should return a 200, the return data in the body, and anX-Location
header, and instead of checking whether the response was redirected, it checks forX-Location
(and hands it to the router hook in 1). This is probably actually the best solution, would just need to handle the equivalent no-JS/server-side behavior.
from leptos.
There are two separate issues here I think:
redirect()
can't work with normal server fn calls Server functions are written in a framework-agnostic way and therefore don't know anything about client-side routing, which is very framework dependent. We are rewriting the whole server function package at the moment, and it would be possible to introduce what's essentially a router hook: if the response is a redirect, the server fn will call that router hook with theLocation
header. Then, the Leptos-specific wrapper for agnostic server functions can provide a router hook that navigates to that.- Browser behavior around 302s This is the "trying to decode HTML as server fn return data" issue. We can't change the browser behavior here, of course. We could decide to bypass it entirely, and use a separate redirect system rather than 302 +
Location
. For example, we could decide thatredirect()
should return a 200, the return data in the body, and anX-Location
header, and instead of checking whether the response was redirected, it checks forX-Location
(and hands it to the router hook in 1). This is probably actually the best solution, would just need to handle the equivalent no-JS/server-side behavior.
I'm always hesitant to do something working around what the browser/html does, but I also am not seeing a great solution for that
from leptos.
Related Issues (20)
- Inconstistency between debug and release on `if let Some(x)...` HOT 5
- Trouble with Events not triggering at all HOT 5
- Can you provide a case of a browser right-click pop-up menu?
- Have signals/StoredValues update/update_value functions return the callbacks return value HOT 6
- examples: add `rust-toolchain.toml` files for examples HOT 1
- Resource::loading gives a warning if disposed before it was fully initialized HOT 2
- leptos_router: Feature: Support for trailing slashes. HOT 13
- Get error about missing "tracing" dependency when trying to use #[component] macro HOT 20
- Route `State` is being lost after Backward and/or Forward navigation
- Improve generic parsing in `view!` macro HOT 1
- compile errors in iterators on stable rust HOT 1
- Use a cloneable type for ActionForm's error prop instead of Box<dyn Error> HOT 2
- Type safe search params in router HOT 2
- Transfer or remove Viz integration? HOT 2
- cargo leptos watch Error: compile sass/scss HOT 2
- trunk serve --open success but no response. HOT 6
- Err(Deserialization("missing field `excluded_tags`")) HOT 4
- Allow to include `view!` content from external file HOT 1
- Support hashstyle routing HOT 1
- SsrMode::Async breaks when mixing blocking/non resources. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from leptos.