javascript Angularjs uri 组件是如何编码的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24542465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angularjs How uri components are encoded
提问by nakhli
I was expecting AngularJS to encode query string parameters using the standard javascript function encodeURIComponent
. According to the following test it is not the case:
我期待 AngularJS 使用标准的 javascript 函数对查询字符串参数进行编码encodeURIComponent
。根据以下测试,情况并非如此:
describe('$http', function () {
it('encodes uri components correctly', inject(function($http, $httpBackend) {
var data = 'Hello from http://example.com';
$httpBackend.expectGET('/api/process?data=' + encodeURIComponent(data));
$http({ method: 'GET', url: '/api/process', params: { data: data } });
$httpBackend.flush();
}));
});
The test fails with the following error:
测试失败并出现以下错误:
$http encodes uri components correctly
Error: Unexpected request: GET /api/process?data=Hello+from+http:%2F%2Fexample.com
Expected GET /api/process?data=Hello%20from%20http%3A%2F%2Fexample.com
$http 正确编码 uri 组件
错误:意外请求:GET /api/process?data=Hello+from+http:%2F%2Fexample.com
预期 GET /api/process?data=Hello%20from%20http%3A%2F% 2Fexample.com
To sum up:
总结:
- Expected encoding:
Hello%20from%20http%3A%2F%2Fexample.com
- Actual encoding:
Hello+from+http:%2F%2Fexample.com
- 预期编码:
Hello%20from%20http%3A%2F%2Fexample.com
- 实际编码:
Hello+from+http:%2F%2Fexample.com
What uri component (aka query string parameters) encoding method should I expect with AngularJS?
AngularJS 应该使用什么 uri 组件(又名查询字符串参数)编码方法?
采纳答案by sylvain
Angular (at least 1.3) doesn't only use encodeURIComponent and changes some replacements (like " " to "+").
Angular(至少 1.3)不仅使用 encodeURIComponent 并且改变了一些替换(比如“”到“+”)。
this is the commit explaining why : https://github.com/angular/angular.js/commit/9e30baad3feafc82fb2f2011fd3f21909f4ba29e
这是解释原因的提交:https: //github.com/angular/angular.js/commit/9e30baad3feafc82fb2f2011fd3f21909f4ba29e
And here's what you can see in 1.3 sources :
这是您在 1.3 来源中可以看到的内容:
/**
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
* method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
* encoded per http://tools.ietf.org/html/rfc3986:
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/
function encodeUriQuery(val, pctEncodeSpaces) {
return encodeURIComponent(val).
replace(/%40/gi, '@').
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%3B/gi, ';').
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
}
note that pctEncodeSpaces
is hardcoded to true
;
请注意,它pctEncodeSpaces
被硬编码为true
;
Here's what you can do to decode URI parameters
您可以执行以下操作来解码 URI 参数
decodeURIComponent(val.
replace('@', '%40').
replace(':', '%3A').
replace('$', '%24').
replace(',', '%2C').
replace(';', '%3B').
replace('+', '%20'));
回答by alediaferia
In my humble opinion AngularJS is wrongly encoding in the same way URI path segments AND URI query parameters. To me this is a bug and I actually issued a pull requestfor fixing it.
在我看来,AngularJS 以同样的方式错误地编码了 URI 路径段和 URI 查询参数。对我来说,这是一个错误,我实际上发出了修复它的拉取请求。
The test I introduce in the pull request actually confirms this bug (tested it with both AngularJS 1.3.*
and current master
).
我在 pull request 中引入的测试实际上证实了这个错误(用 AngularJS1.3.*
和 current对其进行了测试master
)。
回答by John Miller
It appears that when you are passing the parameters pre encoding. You encode the URL but after you pass a non-encoded url through the JSON data parameter. Maybe this alteration to your code will work.
看来,当您传递参数预编码时。您对 URL 进行编码,但在通过 JSON 数据参数传递未编码的 url 之后。也许对您的代码进行这种更改会起作用。
describe('$http', function () {
it('encodes uri components correctly', inject(function($http, $httpBackend) {
var data = encodeURIComponent('Hello from http://example.com');
$httpBackend.expectGET('/api/process?data=' + encodeURIComponent(data));
$http({ method: 'GET', url: '/api/process', params: { data: data } });
$httpBackend.flush();
}));
});
Also, After taking only the URL encoding piece and placing it inside a fiddle: http://jsfiddle.net/eNtgL/1/
此外,在仅获取 URL 编码片段并将其放入小提琴后:http: //jsfiddle.net/eNtgL/1/
It appears to be working correctly, you may want to investigate external factors causing the issue with your URL. There are also several other options described here in this
它似乎工作正常,您可能需要调查导致您的 URL 出现问题的外部因素。这里还描述了其他几个选项