我被fcm的原始json体淹没了:
Body = mochijson2:encode([ {<<"operation">>, <<"create">>},{<<"notification_key_name">>, <<"console group">>},{<<"registration_ids">>, [<<"02aa6XXXX3c9b6d">>,<<"APA91bGtaXXXXXXXXXXXXoi4UH8vIdZk1X67A_9izpSFSHV3BXxdIwG">>]}]).
根据documentation发送POST请求以创建群组:
httpc:request(post, {Url, [{"Authorization", KeyApi}, {"project_id", ProjectId}], "application/json", Body},[{timeout, 5000}], []).
但我收到错误BadJsonFormat:
{ok,{{"HTTP/1.1",400,"Bad Request"},
[{"cache-control","private, max-age=0"},
{"date","Fri, 10 Mar 2017 16:19:37 GMT"},
{"accept-ranges","none"},
{"server","GSE"},
{"vary","Accept-Encoding"},
{"content-length","25"},
{"content-type","application/json; charset=UTF-8"},
{"expires","Fri, 10 Mar 2017 16:19:37 GMT"},
{"x-content-type-options","nosniff"},
{"x-frame-options","SAMEORIGIN"},
{"x-xss-protection","1; mode=block"},
{"alt-svc","quic=\":443\"; ma=2592000; v=\"36,35,34\""}],
"{\"error\":\"BadJsonFormat\"}"}}
但是mochijson2:decode(Body)
工作正常,它看起来像是正确形成的json,但无论如何我都得到错误BadJsonFormat。
出了什么问题?我该如何解决这个问题?
答案 0 :(得分:3)
函数mochijson2:encode
不返回字符串或二进制文件,而是返回一个iolist:
1> Body = mochijson2:encode([ {<<"operation">>, <<"create">>},{<<"notification_key_name">>, <<"console group">>},{<<"registration_ids">>, [<<"02aa6XXXX3c9b6d">>,<<"APA91bGtaXXXXXXXXXXXXoi4UH8vIdZk1X67A_9izpSFSHV3BXxdIwG">>]}]).
[123,
[34,<<"operation">>,34],
58,
[34,<<"create">>,34],
44,
[34,<<"notification_key_name">>,34],
58,
[34,<<"console group">>,34],
44,
[34,<<"registration_ids">>,34],
58,
[91,
[34,<<"02aa6XXXX3c9b6d">>,34],
44,
[34,<<"APA91bGtaXXXXXXXXXXXXoi4UH8vIdZk1X67A_9izpSF"...>>,
34],
93],
125]
这本身没有任何问题。使用iolists而不是字符串或二进制文件意味着您不必创建昂贵的平面数据结构,只需将其写入文件或套接字,然后将其丢弃即可。像file:write_file
和gen_tcp:send
这样的函数处理iolists以及字符串或二进制文件。
但是,httpc:request
没有!
让我们通过在shell中使用netcat在端口1111上启动服务器来测试:
$ nc -l 1111
然后从Erlang shell发出请求:
3> httpc:request(post, {"http://127.0.0.1:1111", [], "application/json", Body},[{timeout, 5000}], []).
netcat服务器显示此输出:
POST / HTTP/1.1
content-type: application/json
content-length: 13
te:
host: 127.0.0.1:1111
connection: keep-alive
{"operation":"create",....
请注意content-length
是13而不是159! httpc:request
能够发送iolist,但它使用函数length
而不是iolist_size
生成content-length
标头,因此服务器只考虑前13个JSON对象的字节,它本身不是有效的JSON。
解决方案是将iolist_to_binary(Body)
传递给httpc:request
,而不只是Body
。