我们需要在url参数中使用编码的分号字符,但angular不会对此字符进行编码。
我们使用的资源看起来像这样:
app.factory('TestResource', ['$resource', function ($resource) {
return $resource('http://somedomain.com');
}]);
app.run(['TestResource', function (TestResource) {
TestResource.query({
q: 'sin;sout'
});
}]);
这是我们得到的结果:
http://somedomain.com/?q=sin;sout
我们希望网址为:
http://somedomain.com/?q=sin%3Bsout
但是如果我们在发送%char get之前对参数进行预编码,则编码如下:
http://somedomain.com/?q=sin%253Bsout
我们如何才能获得理想的结果? (http://somedomain.com/?q=sin%3Bsout)
答案 0 :(得分:5)
Angular使用自己的函数对URL进行编码。并且该函数不会编码通常不需要像/
或?
那样编码的字符。 ;
也是这样一个角色。它用于矩阵URI,例如因此,Angular的行为实际上符合标准,但当字面上使用这些字符时,可能会成为问题,即没有特殊含义。这似乎就是这种情况。
由于URL是在发送请求之前构建的,因此我们无能为力。但是有一个漏洞:只编码参数,而不是基本URL。因此,任何解决方法都需要自己创建URL或至少部分URL。
您可以添加一个拦截器,在Angular执行之前将正确编码的参数添加到URL。你甚至可以用这种方式完全取代Angular的行为。
<强>更新强>
我想到了另一个解决方案。 $http
服务委托将实际请求发送到接收已构造的URL的$httpBackend
服务。使用装饰器,您可以在发送请求之前将;
或编码错误的%253B
替换为%3B
:
app.config(function($provide) {
$provide.decorator('$httpBackend', function($delegate) {
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
url = url.replace(';', '%3B');
$delegate(method, url, post, callback, headers, timeout, withCredentials, responseType);
};
})
});
答案 1 :(得分:2)
在zeroflagL的答案基础上,可以考虑更改替换以更改所有出现的分号(因为它写的只会替换第一个分号):
url = url.replace(/;/g, '%3B');
答案 2 :(得分:0)
您可以使用encodeURIComponent()
方法:
q: encodeURIComponent('sin;sout')
答案 3 :(得分:0)
此https://github.com/angular/angular.js/issues/9224
存在已解决的问题路径:不要使用分号。打破矩阵参数,并且没有证据表明Angular的当前行为存在问题。
查询:转义整个查询字符串是不明智的,因为它打破了服务器能够处理以分号分隔的查询字符串的既定(虽然过时)期望。
查询值:可能安全逃脱,尤其是服务器将分号解释为查询分隔符时。通过查询参数传递复杂数据类型(即JSON)是一个坏主意,但&#34;真实世界&#34;字符串值通常包含分号,并且逃避它们似乎是一个好主意。
我会使用zeroflagL的答案,但只会更改查询值。像这样:
$provide.decorator('$httpBackend', function($delegate) {
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
var a = document.createElement('a');
a.href = url;
if(a.search.length > 1) {
var params = a.search.substring(1).split('&');
for (var i=0; i<params.length; i++) {
var param = params[i].split('=');
if(param[1]) {
params[i] = [param[0], param[1].replace(';', '%3B')].join('=');
}
}
url = url.substring(0, url.lastIndexOf('?')) + '?' + params.join('&');
}
$delegate(method, url, post, callback, headers, timeout, withCredentials, responseType);
};
});