Angular 2 - 发送 Http Get 请求 - 传递 JSON 对象

19
我该如何进行 HTTP GET 请求并传递 JSON 对象?
这是我的 JSON 对象。
{{firstname:"Peter", lastname:"Test"}

我希望把这个对象作为HTTP请求参数传递,以便获取匹配的人员列表。

怎么实现呢?这个例子只展示了一个返回JSON结果的简单GET请求。我需要如何修改它呢?

//Component:

person:Person;
persons:Person [];
....
//Whre can I pass the person, here in the service??
getMatchedPersons(){
  this.httpService.getMatchedPersons().subscribe(
     data =>  this.persons = data,
    error => aller(error)
    );
 ); 
  

  //SERVICE
  //pass parameters?? how to send the person object here?
  getMatchedPersons(){
    return this.http.get('url').map(res => res.json());
  }


我想你要么使用http.post,要么将参数传递到查询字符串中http.get('url?firstname=$1&lastname=$2') - Arg0n
6个回答

5
Http.get方法需要一个实现RequestOptionsArgs接口的对象作为第二个参数。
该对象的search字段可用于设置字符串或URLSearchParams对象。
例如:
 // Parameters obj-
 let params: URLSearchParams = new URLSearchParams();
 params.set('firstname', yourFirstNameData);
 params.set('lastname', yourLastNameData);

 //Http request-
 return this.http.get('url', {
   search: params
 }).subscribe(
   (response) => //some manipulation with response 
 );

11
我简直无法相信他们把本应极其简单的事情搞得这么复杂 :( 不仅仅是 Angular,而且当需要发送带有变量的 GET 请求时,JavaScript 也是如此。如果我们有二十个值,那该怎么办?我们必须遍历对象并手动执行 params.set(key, value) 吗?我简直不敢相信... 我们应该能够告诉它“看,这里有一个对象(或字符串化版本)。对于通过 GET 变量发送它的方式,就按照你需要的方式拆分它即可”。这就足够了。为什么要把事情搞得这么复杂 :( - MrCroft

5

对于纯JavaScript:

你必须将你的JSON序列化为参数列表:

?firstname=peter&lastname=test

由于GET请求没有正文,因此将其附加到URL中。

有几种将JSON转换为查询参数的方法。它们在这个问题中得到了解决:是否有任何本地功能可以将JSON转换为URL参数?

在那里你可以选择你喜欢的方式,我的选择是:

function obj_to_query(obj) {
    var parts = [];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
        }
    }
    return "?" + parts.join('&');
}

请注意,GET请求必须遵守基于此答案的URL限制,建议保持在2000个字符以下以确保安全:

RFC规定为8000
IE8和IE9最远可达2083
搜索引擎只读取2048个字符

使用Angular2 URLSearchParams

使用将普通JSON转换为参数的同一方法,可以像Рома Скидан建议的那样使用URLSearchParams
 let params: URLSearchParams = objToSearchParams(obj);

 return this.http.get('url', {
   search: params
 }).subscribe(
   (response) => //some manipulation with response 
 );

 function objToSearchParams(obj): URLSearchParams{
    let params: URLSearchParams = new URLSearchParams();
    for (var key in obj) {
        if (obj.hasOwnProperty(key))
            params.set(key, obj[key]);
    }
    return params;
 }

当你说:“GET请求没有正文”时,这本身是错误的。请参考此链接:https://dev59.com/53NA5IYBdhLWcg3wZ85S 如果我误解了你回答的上下文,请纠正我。 - Ashish Goyal
@AshishGoyal 这正是我所说的。按照惯例,GET请求将忽略其body部分。 - SparK

4
也许您想将JSON对象转换成字符串。
var json = JSON.stringify(myObj);

this.http.get('url'+'?myobj='+encodeURIComponent(json))

我的对象={"公司名称":"Typhany&Co."}...使用包含“&”的字符串中断API通信?检查。 - SparK
2
当然,不要忘记对其进行编码 myobj= encodeURIComponent(myobj) - null canvas
1
这是最短和最好的答案。谢谢你。在后端,使用node.js只需执行JSON.parse(req.query.obj) - Thomas Cayne

0
使用 POST 请求将对象传递到服务器:
//SERVICE
getMatchedPersons(searchObj: any){
    return this.http.post('url', JSON.stringify(searchObj))
                    .map(res => res.json());
}

然后你可以传递任何JS对象,并将其发送到您的HTTP请求中的服务器。

getMatchedPersons(searchObj: any){
    this.httpService.getMatchedPersons(searchObj: any).subscribe(
        data =>  this.persons = data,
        error => alert(error);
    );
); 

真的,但你不能通过GET传递对象 - 我可以认为这是一种策略性的反对票吗? ;) - Maximilian Riegler
1
你可以将它们序列化,如果需要的话。 - null canvas
1
这是 @Arg0n 建议的。但我认为它应该是一个 GET 请求,想象一下这是一个搜索/筛选条件对象,返回一个搜索结果列表。 - null canvas
3
@rinukkusu,我同意你的观点,REST并不完美,但我也同意AngJobs的看法,即获取对象和其他不会改变服务器内容的请求应该是可重放的,因此使用get方法。如果对象仅是搜索过滤器,并且您使用post方法进行搜索,则意味着您认为谷歌做错了... - SparK
一定要遵循HTTP规范... GET和POST不是我们可以轻易对待的东西。一个理由来源:https://medium.com/@suhas_chatekar/why-you-should-use-the-recommended-http-methods-in-your-rest-apis-981359828bf7 - Kris Boyd
显示剩余3条评论

0

实际上,有一种更简单的方式来刷新参数

getMatchedPersons(myObject: any): Observable<Person[]> {
    return this.http.get<Person[]>('url', { params: { ...myObject } });
}
  • 上述代码表示一个接受JSON对象myObject作为参数的函数。

  • HttpClient.get方法接受一个options参数作为它的第二个参数。

  • options参数包含许多有用的键,但在我们的情况下,我们只关心params键。

  • params的值是{ ...myObject },也就是说- 我们使用展开运算符从一个对象中传递所有的key:value对。

请注意,这将完成工作,并且不会使URL看起来很丑陋,因为所有那些?key=value&字符,在任何情况下,这些参数都不会显示给用户,因为这只是一个HTTP调用,但是,如果有人使用了日志记录器interceptor,他们将拥有一个干净的日志。


0

类似于AngJobs,但可能更加现代化?调用encodeURIComponent不是必需的。这是Angular:

const stringifiedParams = JSON.stringify(this.filterParams);
return this.http.get<any[]>(`persons`, {params: {filter: stringifiedParams}});

在服务器上,Node使用JSON.parse对参数进行反序列化:
filter = JSON.parse(req.query.filter.toString());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接