mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-24 03:55:49 +08:00
fix(Angular.js): handle duplicate params in parseKeyValue/toKeyValue
parseKeyValue and toKeyValue can now handle duplicate values in the query.
```
?x=1&x=2 <-> {x:[1,2]}
```
The algorithm looks like:
1)parseKeyValue looks for presence of obj[key]
2)detects and replaces obj[key] with [obj[key],val]
3)then pushes more duplicates if necessary
4)toKeyValue decodes array correctly
5)(not changed)$location.search({param: 'key'}) still replaces if necessary
6)(not changed)$location.search({param: ['key1', 'key2']}) sets the url with duplicates
BREAKING CHANGE: Before this change:
- `parseKeyValue` only took the last key overwriting all the previous keys;
- `toKeyValue` joined the keys together in a comma delimited string.
This was deemed buggy behavior. If your server relied on this behavior
then either the server should be fixed or a simple serialization of
the array should be done on the client before passing it to $location.
This commit is contained in:
committed by
Pete Bacon Darwin
parent
a258817310
commit
807394095b
@@ -318,10 +318,21 @@ describe('angular', function() {
|
||||
expect(parseKeyValue('invalid=%')).toEqual({ invalid: undefined });
|
||||
expect(parseKeyValue('invalid=%&valid=good')).toEqual({ invalid: undefined, valid: 'good' });
|
||||
});
|
||||
it('should parse a string into key-value pairs with duplicates grouped in an array', function() {
|
||||
expect(parseKeyValue('')).toEqual({});
|
||||
expect(parseKeyValue('duplicate=pair')).toEqual({duplicate: 'pair'});
|
||||
expect(parseKeyValue('first=1&first=2')).toEqual({first: ['1','2']});
|
||||
expect(parseKeyValue('escaped%20key=escaped%20value&&escaped%20key=escaped%20value2')).
|
||||
toEqual({'escaped key': ['escaped value','escaped value2']});
|
||||
expect(parseKeyValue('flag1&key=value&flag1')).
|
||||
toEqual({flag1: [true,true], key: 'value'});
|
||||
expect(parseKeyValue('flag1&flag1=value&flag1=value2&flag1')).
|
||||
toEqual({flag1: [true,'value','value2',true]});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toKeyValue', function() {
|
||||
it('should parse key-value pairs into string', function() {
|
||||
it('should serialize key-value pairs into string', function() {
|
||||
expect(toKeyValue({})).toEqual('');
|
||||
expect(toKeyValue({simple: 'pair'})).toEqual('simple=pair');
|
||||
expect(toKeyValue({first: '1', second: '2'})).toEqual('first=1&second=2');
|
||||
@@ -330,9 +341,15 @@ describe('angular', function() {
|
||||
expect(toKeyValue({emptyKey: ''})).toEqual('emptyKey=');
|
||||
});
|
||||
|
||||
it('should parse true values into flags', function() {
|
||||
it('should serialize true values into flags', function() {
|
||||
expect(toKeyValue({flag1: true, key: 'value', flag2: true})).toEqual('flag1&key=value&flag2');
|
||||
});
|
||||
|
||||
it('should serialize duplicates into duplicate param strings', function() {
|
||||
expect(toKeyValue({key: [323,'value',true]})).toEqual('key=323&key=value&key');
|
||||
expect(toKeyValue({key: [323,'value',true, 1234]})).
|
||||
toEqual('key=323&key=value&key&key=1234');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -368,6 +368,29 @@ describe('$location', function() {
|
||||
locationUrl.search('q', '1/2 3');
|
||||
expect(locationUrl.search()).toEqual({'q': '1/2 3'});
|
||||
});
|
||||
|
||||
it('should return an array for duplicate params', function() {
|
||||
var locationUrl = new LocationHtml5Url('http://host.com');
|
||||
locationUrl.$$parse('http://host.com')
|
||||
locationUrl.search('q', ['1/2 3','4/5 6']);
|
||||
expect(locationUrl.search()).toEqual({'q': ['1/2 3','4/5 6']});
|
||||
});
|
||||
|
||||
it('should encode an array correctly from search and add to url', function() {
|
||||
var locationUrl = new LocationHtml5Url('http://host.com');
|
||||
locationUrl.$$parse('http://host.com')
|
||||
locationUrl.search({'q': ['1/2 3','4/5 6']});
|
||||
expect(locationUrl.absUrl()).toEqual('http://host.com?q=1%2F2%203&q=4%2F5%206');
|
||||
});
|
||||
|
||||
it('should rewrite params when specifing a single param in search', function() {
|
||||
var locationUrl = new LocationHtml5Url('http://host.com');
|
||||
locationUrl.$$parse('http://host.com')
|
||||
locationUrl.search({'q': '1/2 3'});
|
||||
expect(locationUrl.absUrl()).toEqual('http://host.com?q=1%2F2%203');
|
||||
locationUrl.search({'q': '4/5 6'});
|
||||
expect(locationUrl.absUrl()).toEqual('http://host.com?q=4%2F5%206');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user