Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

javascript - AngularJS resource: how to disable url entity encoding

On my current project I have a drupal backend that exposes rest services for my frontend. Some calls to my backend don't really like url entities to get encoded.

So my question is: how do I disable URL encoding of some parameters?

Example:

I need to call my backend with a "+"-sign between different search terms. Like so:

http://backend.com/someservice/search/?terms=search+terms+here

But angular, setup like so:

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

Calls the following url:

http://backend.com/someservice/search/?terms=search%2Bterms%2Bhere

Any suggestions? Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update: with the new httpParamSerializer in Angular 1.4 you can do it by writing your own paramSerializer and setting $httpProvider.defaults.paramSerializer.

Below only applies to AngularJS 1.3 (and older).

It is not possible without changing the source of AngularJS.

This is done by $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;
}

encodeUriQuery uses the standard encodeUriComponent (MDN) which replaces the '+' with '%2B'

Too bad you cannot overwrite encodeUriQuery because it is a local variable inside the angular function.

So the only option I see is to overwrite window.encodeURIComponent. I've done it in an $http interceptor to minimize the impact. Note that the original function is only put back when the response comes back, so this change is global (!!) while your request is ongoing. So be sure to test if this doesn't break something else in your application.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...