Support #3753
openUrls with query parameters
0%
Description
I've been using Wt for about a couple of years by still can't understand how query parameters in Wt urls should be handled properly.
I have two anchor widgets that should change the app internal path:
Wt::WApplication *app = new WaApplication(env);
Wt::WAnchor *a1 = new Wt::WAnchor(app->root());
a1->setText("change path");
a1->setLink(Wt::WLink (Wt::WLink::InternalPath, "/change1"));
app->root()->addWidget(new Wt::WBreak);
app->root()->addWidget(new Wt::WBreak);
Wt::WAnchor *a2 = new Wt::WAnchor(app->root());
a2->setText("change path with query");
a2->setLink(Wt::WLink(Wt::WLink::InternalPath, "/change2?my_param=123"));
I launch my app with the internal path = '/'. Then I start clicking my anchors one after another:
app start: http://127.0.0.1:9097/wt/
a1: http://127.0.0.1:9097/wt/change1
a2: http://127.0.0.1:9097/wt/change2?my_param=123
a1: http://127.0.0.1:9097/wt/change1?my_param=123
a2: http://127.0.0.1:9097/wt/change2?my_param=123?my_param=123
a1: http://127.0.0.1:9097/wt/change1?my_param=123?my_param=123
a2: http://127.0.0.1:9097/wt/change2?my_param=123?my_param=123?my_param=123
As you can see, every time I click anchor 'a2' the query parameter pair is appended to the browser url. But WApplication
internalPathChanged
signal always says that the internal path is changing from /change1
to /change2?my_param=123
and back.
I've tried to investigate that problem and found some strange line of code in the WT.history.navigate
function (Wt.js
):
navigate: function (state, generateEvent) {
WT.resolveRelativeAnchors();
currentState = state;
var ip = gentleURIEncode(state), url = baseUrl;
if (ip.length != 0)
url += (ugly ? "?_=" : "") + state;
if (!ugly) {
url += window.location.search;
} else {
Actually I've got some doubts about this line:
url += window.location.search;
Why is the location query part always appended to the current url?
In my application I would like to manage the internal path including its query section. I mean the possibility to change the internal path (and url in browser) like this: wApp->setInternalPath("/page?param=value", false);
and have url looking in browser like http://127.0.0.1:9097/wt/page?param=value
and not http://127.0.0.1:9097/wt/page?param=value?some_old_param=123
.
Updated by Koen Deforche over 9 years ago
- Tracker changed from Bug to Support
- Status changed from New to Feedback
- Assignee set to Koen Deforche
- Target version set to 3.3.4
Hey,
This is something that isn't properly documented. An internal path coincides only with the CGI 'path info', i.e. the path internal to your deployment path but excluding query parameters. The API however doesn't deal with the query parameters consistently: they should probably be ignored or raised as an error in setInternalPath().
The main reason why we exclude query parameters is cross-platform compatibility: on older browsers (pre-HTML5) we have to implement this functionality using the 'hash' trick (i.e. /page#/change1) since only the fragment can be modified without triggering a page reload, and thus query parameters cannot be added.
Of course as time evolves, this becomes a misfeature, and perhaps we should implement a new feature to have a configuration setting in which old browser support is dropped and instead query parameters are supported in the way you would like.
Updated by Benoit Daccache about 9 years ago
- Target version changed from 3.3.4 to 3.3.5
Updated by Adrian B over 3 years ago
I have the same problem.
If I only want to support recent browsers, may I delete the line below in Wt.js without breaking something ?
url += window.location.search;
P.S. - I'm still using Wt 3.3.1.
Updated by Adrian B over 3 years ago
The history back and forward of the browser now triggers a refresh of the page (thus terminating the session), but it seems to work.
If you know of any other side effects that it may cause, don't hesitate to add it.
Updated by Korneel Dumon over 3 years ago
- Description updated (diff)
The url parameters are part of WEnvironment which does not change, so therefore the parameter is also preserved in the URL.
What is your use case for internal paths with parameters? Perhaps you can replace it by simply changing some state in the server when the link is clicked?
Updated by Adrian B over 3 years ago
The use case :
In our application, the user can select values for multiples filters in order to search information in a database.
We want to use the query string and setInternalPath() to update the URL with the filters values when a search is made, so the user can copy the URL to easily save or share them.
Updated by Adrian B over 3 years ago
Adrian B wrote in #note-4:
The history back and forward of the browser now triggers a refresh of the page (thus terminating the session), but it seems to work.
It was a mistake on my part, this behavior did not change. I compared the old and new behavior of history naviguation with two different methods :
- After the manual change of the URL and a refresh → history naviguation trigger will trigger a refresh.
- After the change of the URL with setInternalPath() → history naviguation trigger will not trigger a refresh.
Updated by Korneel Dumon over 3 years ago
Thanks for the feedback on the use-case, sounds pretty valid to me. If support is added, it will not be in Wt 3 since no new features are added there.
About your original question: if you configure 'reload-is-new-session' to false we include the session-id as a url-parameter so this will no longer work.
Updated by Adrian B over 3 years ago
Thanks.
If support is added, it will not be in Wt 3 since no new features are added there.
I would not expect otherwise :).
if you configure 'reload-is-new-session' to false we include the session-id as a url-parameter so this will no longer work.
As you seem to be parts of Wt's developers team, if it's not too much to ask, could you give your degree of confidence that it would be the only thing that would break ?
In order to know if we could disable the line (pretty much) safely if we don't expect to include a session-id in the URL - which is not recommended anyway - nor to be compatible with pre-HTML5 browsers.
For others that would fall upon this issue : another possibility would be to add a button which creates and copies the URL with the query string in the clipboard.
Unfortunately, it's less user-friendly and if the session is terminated (by example, after a timeout or a refresh) the user loses all the data that would otherwise be saved in the URL if it was directly changed in the browser.