Merge pull request #501 from sveltejs/gh-497

consistent query parameter handling between client and server
This commit is contained in:
Rich Harris
2018-10-27 12:35:58 -04:00
committed by GitHub
5 changed files with 33 additions and 15 deletions

View File

@@ -87,11 +87,14 @@ export function select_route(url: URL): Target {
const match = page.pattern.exec(path); const match = page.pattern.exec(path);
if (match) { if (match) {
const query: Record<string, string | true> = {}; const query: Record<string, string | string[]> = Object.create(null);
if (url.search.length > 0) { if (url.search.length > 0) {
url.search.slice(1).split('&').forEach(searchParam => { url.search.slice(1).split('&').forEach(searchParam => {
const [, key, value] = /([^=]*)(?:=(.*))?/.exec(searchParam); let [, key, value] = /([^=]*)(?:=(.*))?/.exec(decodeURIComponent(searchParam));
query[decodeURIComponent(key)] = decodeURIComponent((value || '').replace(/\+/g, ' ')); value = (value || '').replace(/\+/g, ' ');
if (typeof query[key] === 'string') query[key] = [<string>query[key]];
if (typeof query[key] === 'object') query[key].push(value);
else query[key] = value;
}); });
} }
return { url, path, page, match, query }; return { url, path, page, match, query };

View File

@@ -55,7 +55,7 @@ export type Target = {
path: string; path: string;
page: Page; page: Page;
match: RegExpExecArray; match: RegExpExecArray;
query: Record<string, string | true>; query: Record<string, string | string[]>;
}; };
export type Redirect = { export type Redirect = {

View File

@@ -1,9 +1 @@
<h1>message: "{message}"</h1> <h1>{JSON.stringify(query)}</h1>
<script>
export default {
preload({ query }) {
return query;
}
};
</script>

View File

@@ -3,5 +3,6 @@
<a href="a">a</a> <a href="a">a</a>
<a href="ambiguous/ok.json">ok</a> <a href="ambiguous/ok.json">ok</a>
<a href="echo-query?message">ok</a> <a href="echo-query?message">ok</a>
<a href="echo-query?p=one&p=two">ok</a>
<div class='hydrate-test'></div> <div class='hydrate-test'></div>

View File

@@ -204,7 +204,7 @@ describe('basics', function() {
assert.equal( assert.equal(
await title(), await title(),
'message: ""' '{"message":""}'
); );
}); });
@@ -217,7 +217,29 @@ describe('basics', function() {
assert.equal( assert.equal(
await title(), await title(),
'message: ""' '{"message":""}'
);
});
it('accepts duplicated query string parameter on server', async () => {
await page.goto(`${base}/echo-query?p=one&p=two`);
assert.equal(
await title(),
'{"p":["one","two"]}'
);
});
it('accepts duplicated query string parameter on client', async () => {
await page.goto(base);
await start();
await prefetchRoutes();
await page.click('a[href="echo-query?p=one&p=two"]')
assert.equal(
await title(),
'{"p":["one","two"]}'
); );
}); });