Angularjs Angular不编码url中的分号字符

Angularjs Angular不编码url中的分号字符,angularjs,Angularjs,我们需要在url参数中使用编码分号字符,但angular不编码此字符 我们使用的资源如下所示: app.factory('TestResource', ['$resource', function ($resource) { return $resource('http://somedomain.com'); }]); app.run(['TestResource', function (TestResource) { TestResource.query({

我们需要在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%253Bsout
这是我们得到的结果:

http://somedomain.com/?q=sin;sout
我们希望url为:

http://somedomain.com/?q=sin%3Bsout
但是如果我们在发送%char get之前对参数进行预编码,则编码如下:

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%253Bsout

我们怎样才能得到期望的结果?()

您可以使用
encodeURIComponent()
方法:

q: encodeURIComponent('sin;sout')

Angular使用自己的函数对URL进行编码。该函数不编码通常不需要编码的字符,如
/
<代码>也是这样一个字符。它用于矩阵URI中,例如,Angular的行为实际上符合标准,但如果按字面意思使用此类字符,即没有特殊含义,则可能会出现问题。这里似乎就是这样

由于URL是在发送请求之前构建的,因此我们无能为力。不过也有一个漏洞:只对参数进行编码,而不是对基本URL进行编码。因此,任何解决方法都需要自己创建URL或至少部分URL

您可以添加一个拦截器,在Angular执行之前将正确编码的参数添加到URL。你甚至可以用这种方式完全取代Angular的行为

更新:

我想到了另一个解决办法。
$http
服务将实际请求发送到接收已构建URL的
$httpBackend
服务。使用装饰器,您可以替换
或在发送请求之前用
%3B
正确编码的
%253B

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);
    };
  })
});

<0>建立在ZoFrAGLL的回答上,可以考虑改变替换来改变所有的半结肠的出现(如它所写的那样,它只替换第一个半结肠):


这是一个封闭的问题

路径:不要转义分号。打断矩阵参数,并且没有证据表明Angular的当前行为有问题

query:对整个查询字符串进行转义是不明智的,因为它打破了对服务器能够处理分号分隔的查询字符串的既定(尽管是过时的)期望

查询值:可以安全地转义,特别是当服务器将分号解释为查询分隔符时。通过查询参数传递复杂的数据类型(例如JSON)是一个坏主意,但是“真实世界”的字符串值通常包含分号,并且转义它们似乎是一个好主意

我将使用的答案,但只更改查询值。像这样:

$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);
    };
});
$provide.decorator('$httpBackend',函数($delegate){
返回函数(方法、url、post、回调、标题、超时、withCredentials、responseType){
var a=document.createElement('a');
a、 href=url;
如果(a.search.length>1){
var params=a.search.substring(1).split('&');

对于(var i=0;它不适用于我们,angular似乎也对字符串进行编码,因此我们得到结果:(%253B应该是%3B)这听起来可能是一个愚蠢的问题,但为什么您认为URL没有正确编码?根据您检查的方式,您可能会实际看到已解码的URL。此外,编码与否应该不会有什么区别。通常在发生任何事情之前,它会在服务器端解码。我们使用它来为XDB构建查询。我们可以看到URL simply在浏览器中,如果我们手动更改URL,它就会工作。作为一种解决方法,我们现在使用jQuery和一个ajax请求来正确编码URL。