Skip to content

Commit ca7bee0

Browse files
committed
URL-encode path parameters for Router.url
The main breaking change from v8.x to v9.x was an upgrade to `path-to-regex`. [That PR](koajs#71) alluded to a breaking change in encoding. Namely, parameters were not URL-encoded: parameters with safe special characters (like spaces) were not percent-encoded, and parameters with special characters that mean something in a URL, such as slashes (path separators) and question marks (query string delimiter). The motivation for this PR is to make URL-encoding be the default since typically the parameters provided to `Router.url` are plain, unencoded values. Should someone need an escape hatch, they could pass in `{ encode: null }` (I think) to disable the automatic encoding. Updated tests, docs, and the changelog.
1 parent 344ba0b commit ca7bee0

File tree

5 files changed

+20
-8
lines changed

5 files changed

+20
-8
lines changed

API.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ router
382382
<a name="module_koa-router--Router.url"></a>
383383

384384
#### Router.url(path, params) ⇒ <code>String</code>
385-
Generate URL from url pattern and given `params`.
385+
Generate URL from the given URL pattern and `params`. This method URL-encodes the parameters before including them in the URL.
386386

387387
**Kind**: static method of <code>[Router](#exp_module_koa-router--Router)</code>
388388

history.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
Next
2+
==================
3+
4+
- [Breaking] URL-encode parameters passed to `Router.url` with `encodeURIComponent`.
5+
- Previously, the parameters to insert in a URL were not encoded: `Router.url('/:x', { x: 'hello world' })` produced `"/hello world"` and `Router.url('/:x', { x: 'a/test?param#' })` would throw an error.
6+
- Now, all parameters are safely URL-encoded by default: `Router.url('/:x', { x: 'hello world' })` produces `"/hello%20world"` and `Router.url('/:x', { x: 'a/test?param#' })` produces `"/a%2Ftest%3Fparam%23"`.
7+
18
9.0.0 / 2020-04-09
29
==================
310

lib/layer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ Layer.prototype.url = function (params, options) {
118118
}
119119
}
120120

121-
const toPath = compile(url, options);
121+
const toPath = compile(url, Object.assign({ encode: encodeURIComponent }, options));
122122
let replaced;
123123

124124
const tokens = parse(url);

test/lib/layer.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,8 @@ describe('Layer', function() {
239239

240240
it('escapes using encodeURIComponent()', function() {
241241
const route = new Layer('/:category/:title', ['get'], [function () {}], {name: 'books'});
242-
const url = route.url(
243-
{ category: 'programming', title: 'how to node' },
244-
{ encode: encodeURIComponent }
245-
);
246-
url.should.equal('/programming/how%20to%20node');
242+
const url = route.url({ category: 'programming', title: 'how to node & js/ts' });
243+
url.should.equal('/programming/how%20to%20node%20%26%20js%2Fts');
247244
});
248245

249246
it('setPrefix method checks Layer for path', function () {
@@ -269,4 +266,4 @@ describe('Layer', function() {
269266
prefix.path.should.equal(false)
270267
});
271268
});
272-
});
269+
});

test/lib/router.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,14 @@ describe('Router', function () {
15011501
.url("Picard", "Enterprise")
15021502
.should.Error();
15031503
});
1504+
1505+
it('escapes using encodeURIComponent()', function() {
1506+
const url = Router.url(
1507+
'/:category/:title',
1508+
{ category: 'programming', title: 'how to node & js/ts' }
1509+
);
1510+
url.should.equal('/programming/how%20to%20node%20%26%20js%2Fts');
1511+
});
15041512
});
15051513

15061514
describe('Router#param()', function () {

0 commit comments

Comments
 (0)