AngularJS资源:如何禁用url实体编码

pol*_*ick 14 javascript rest angularjs

在我目前的项目中,我有一个drupal后端,为我的前端公开了休息服务.对我的后端的一些调用并不像url实体那样被编码.

所以我的问题是:如何禁用某些参数的URL编码?

例:

我需要在不同的搜索字词之间用"+"标记我的后端.像这样:

http://backend.com/someservice/search/?terms=search+terms+here
Run Code Online (Sandbox Code Playgroud)

但角度,设置如下:

var resource = $resource(
  backendUrl + '/views/:view', {},
    {
      'search': {params:{view:'searchposts'}, isArray:true}
    }
 );

// search posts for the given terms
this.searchPosts = function(terms, limit) {
  resource.search({search:terms.join('+'), limit:limit});
};
Run Code Online (Sandbox Code Playgroud)

调用以下网址:

http://backend.com/someservice/search/?terms=search%2Bterms%2Bhere
Run Code Online (Sandbox Code Playgroud)

有什么建议?谢谢!

Pie*_*len 9

更新:使用Angular 1.4中的新httpParamSerializer,您可以通过编写自己的paramSerializer和设置来完成$httpProvider.defaults.paramSerializer.

以下仅适用于AngularJS 1.3(及更早版本).

如果不改变AngularJS的来源是不可能的.

这是由$ http完成的:

https://github.com/angular/angular.js/tree/v1.3.0-rc.5/src/ng/http.js#L1057

function buildUrl(url, params) {
      if (!params) return url;
      var parts = [];
      forEachSorted(params, function(value, key) {
        if (value === null || isUndefined(value)) return;
        if (!isArray(value)) value = [value];

        forEach(value, function(v) {
          if (isObject(v)) {
            v = toJson(v);
          }
          parts.push(encodeUriQuery(key) + '=' +
                     encodeUriQuery(v));
        });
      });
      if(parts.length > 0) {
        url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
      }
      return url;
}
Run Code Online (Sandbox Code Playgroud)

encodeUriQuery使用标准encodeUriComponent(MDN)将'+'替换为'%2B'

太糟糕了,你不能覆盖encodeUriQuery因为它是angular函数内的局部变量.

所以我看到的唯一选择是覆盖window.encodeURIComponent.我已经在$ http拦截器中完成了它,以尽量减少影响.请注意,原始功能仅在响应返回时放回,因此在您的请求正在进行时,此更改是全局的(!!).因此,请务必测试这是否会破坏您应用程序中的其他内容.

app.config(function($httpProvider) {
  $httpProvider.interceptors.push(function($q) {
    var realEncodeURIComponent = window.encodeURIComponent;
    return {
      'request': function(config) {
         window.encodeURIComponent = function(input) {
           return realEncodeURIComponent(input).split("%2B").join("+"); 
         }; 
         return config || $q.when(config);
      },
      'response': function(config) {
         window.encodeURIComponent = realEncodeURIComponent;
         return config || $q.when(config);
      }
    };
  });
});
Run Code Online (Sandbox Code Playgroud)