Angular http request with json param

2019-07-10 14:11发布

问题:

In my RESTful api one of the resources exposes a GET method that accept json as a parameter named 'query'. This parameter is passed directly to the MongoDB query allowing users to query the database directly using mongo syntax.

The problem I'm having is that the request always looks like this:

?&query=%7B%22source%22:%22incident%22%7D 

Where it should look something like this:

?&query={'source': 'incident'} 

This is how I am sending the GET request:

var query = {};
if ($scope.sourceFilter) { query.source = $scope.sourceFilter; }
    var query = JSON.stringify(query);
    $http.get('/api/feedbackEntries', {params: {limit: $scope.limit, query: query}}).success(function(data) { .......

I am doing the same thing on other get requests and I don't get this issue.

Am I doing something wrong here ? Is this to do with the way angular parses params ?

Thanks

回答1:

Like the $http docs say

params{Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

Latter emphasis is added by me.

So the query property of the object you pass to the params configuration option is an Object. This means is will be JSONified, which means the same as

JSON.stringify(query);

So this

{'source': 'incident'}

Turns to this:

'{"source": "incident"}'

As RFC 1738 states:

... only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL.

As it happens {, } and " are not on that list and have to be url encoded to be used in a url. In your case %7B corresponds to {, %7D corresponds to } and %22 corresponds to ".

So what is happening is normal and most server software automatically decodes the url query parameters for you, so they will be presented normally. Most likely you'll need to parse it back to JSON somehow!

Hope this helps!



回答2:

When using RESTFul apis concider using ngResource, ngResource docs

Include it in your module:

yourApp = angular.module('yourApp', ['ngResource'])

Add your service:

yourApp.factory('YourService', ['$resource', function($resource){
return $resource('link/to/your/object', {});
}]);

Add your controller

yourApp.controller('YourController', [$scope, 
'YourService', function($scope, YourService) {

$scope.yourData = YourService.get(); 
$scope.yourData = YourService.query(); //(When obtaining arrays from JSON.)

I've found this is the best way using a RESTFull api.



回答3:

After some digging I figured this one out. Looking at the request I was making:

$http.get('/api/feedbackEntries',

I saw that the url does not end with a trailing slash. This was the only difference I could see compared with other requests that were working fine. So I added the trailing slash and magically it works. I can't explain why, whether it's something within angular or elsewhere .. but this is how I fixed the problem.

Hope this helps someone in the future.



回答4:

Below is the code I used to get search result from my server, it works for me sending POST request with JSON params without .

var service = {
  getResult: function ({"username": "roman", "gender": "male"}) {

    var promise = $http({
      url: ServerManager.getServerUrl(),
      method: "POST",
      data: params,
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .success(function (data, status, headers, config) {
      console.log('getResult success.');
      return data;

    }).error(function (data, status) {
      console.log('getResult error.');
    });

    return promise;
  }
}
return service;