Erlang Thursday – httpc:request/1 and httpc:request/4

今天的 Erlang Thursday 讲的是 httpc:request/1httpc:request/4 。httpc模块是erlang的HTTP1.1 客户端,request函数是erlang的功能强大的web请求工具。

要使用httpc模块,我们必需先确保 inets 已经启动。

1
2
inets:start().
% ok

httpc:requst/1 接收一个入参,就是一个RUL,它是一个erlang字符串,也就是你需要访问的地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
httpc:request("http://www.example.com").
% {ok,{{"HTTP/1.1",200,"OK"},
% [{"cache-control","max-age=604800"},
% {"date","Thu, 22 Jan 2015 02:57:06 GMT"},
% {"accept-ranges","bytes"},
% {"etag",""359670651""},
% {"server","ECS (ftw/FBE4)"},
% {"content-length","1270"},
% {"content-type","text/html"},
% {"expires","Thu, 29 Jan 2015 02:57:06 GMT"},
% {"last-modified","Fri, 09 Aug 2013 23:54:35 GMT"},
% {"x-cache","HIT"},
% {"x-ec-custom-error","1"}],
% "<!doctype html>n<html>n<head>n <title>Example Domain</title>nn <meta ..."}}

httpc:request/1 和 httpc:request/4 功能是一样的, 相当于 httpc:request(get, {Url, []}, [], []) 这样被调用一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
httpc:request(get, {"http://www.example.com", []}, [], []).
% {ok,{{"HTTP/1.1",200,"OK"},
% [{"cache-control","max-age=604800"},
% {"date","Thu, 22 Jan 2015 03:04:31 GMT"},
% {"accept-ranges","bytes"},
% {"etag",""359670651""},
% {"server","ECS (ftw/FBE4)"},
% {"content-length","1270"},
% {"content-type","text/html"},
% {"expires","Thu, 29 Jan 2015 03:04:31 GMT"},
% {"last-modified","Fri, 09 Aug 2013 23:54:35 GMT"},
% {"x-cache","HIT"},
% {"x-ec-custom-error","1"}],
% "<!doctype html>n<html>n<head>n <title>Example Domain</title>nn <meta ..."}}

我们可以指定我们请求的头部内容。比如,我们想得到在瑞典的DuckDuckGo主页来纪念Erlang由由爱立信创建。为了实现这个功能,我们增加一个元组{“Accept-Language”, “sv”}到请求的头部列表。

1
2
3
4
5
6
7
8
9
10
11
12
httpc:request(get, {"http://duckduckgo.com/", [{"Accept-Language", "sv"}]}, [], []).
% {ok,{{"HTTP/1.1",200,"OK"},
% [{"cache-control","max-age=1"},
% {"connection","keep-alive"},
% {"date","Thu, 22 Jan 2015 03:19:29 GMT"},
% {"accept-ranges","bytes"},
% {"etag",""54bfe2a8-1488""},
% {"server","nginx"},
% {"content-length","5256"},
% {"content-type","text/html; charset=UTF-8"},
% {"expires","Thu, 22 Jan 2015 03:19:30 GMT"}],
% "<!DOCTYPE html>n<!--[if IEMobile 7 ]> <html lang="sv_SE" class="no-js iem7"> ..."}}

httpc:request/4 的第三个入参是一个HTTP选项元组组成的列表。比如,你必需设置一个返回超时来避免从一个不可靠的或者一个不能及时返回的慢网站等待结果,请求代码需要回撤并稍后再尝试从而避免触发服务拒绝的攻击后果。下面的例子,我指定一个超时时间为0,单位是毫秒,来确保上述描述的目的。

1
2
3
httpc:request(get, {"http://erlang.org/", []}, [{timeout, 0}], []).
{error,{failed_connect,[{to_address,{"erlang.org",80}},
{inet,[inet],timeout}]}}

httpc:request/4 的最后一个入参是一个选项列表,它们是Erlang这端如何工作的选项。比如,你想异步请求,并在它完成后收到一条消息,这样你需要指定元组{sync, false}作为选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{ok, RequestId} = httpc:request(get, {"http://www.example.com", []}, [], [{sync, false}]).
% {ok,#Ref<0.0.0.179>}
receive {http, {RequestId, Result}} -> Result after 500 -> error end.
% {{"HTTP/1.1",200,"OK"},
% [{"cache-control","max-age=604800"},
% {"date","Thu, 22 Jan 2015 03:08:41 GMT"},
% {"accept-ranges","bytes"},
% {"etag",""359670651""},
% {"server","ECS (ftw/FBE4)"},
% {"content-length","1270"},
% {"content-type","text/html"},
% {"expires","Thu, 29 Jan 2015 03:08:41 GMT"},
% {"last-modified","Fri, 09 Aug 2013 23:54:35 GMT"},
% {"x-cache","HIT"},
% {"x-ec-custom-error","1"}],
% <<"<!doctype html>n<html>n<head>n <title>Example Domain</title>nn <meta "...>>}

或者如果你想返回结果用Erlang二进制而不是Erlang字符串,你可以这么指定选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
httpc:request(get, {"http://www.example.com", []}, [], [{body_format, binary}]).
% {ok,{{"HTTP/1.1",200,"OK"},
% [{"cache-control","max-age=604800"},
% {"date","Thu, 22 Jan 2015 03:58:55 GMT"},
% {"accept-ranges","bytes"},
% {"etag",""359670651""},
% {"server","ECS (ftw/FBE4)"},
% {"content-length","1270"},
% {"content-type","text/html"},
% {"expires","Thu, 29 Jan 2015 03:58:55 GMT"},
% {"last-modified","Fri, 09 Aug 2013 23:54:35 GMT"},
% {"x-cache","HIT"},
% {"x-ec-custom-error","1"}],
% <<"<!doctype html>n<html>n<head>n <title>Example Domain</title>nn <meta "...>>}}

这篇文章仅仅是描述了你可以用httpc:request/4 来做一些很简单的事情。我强烈建议你阅读Erlang官方文档的httpc模块部分。更多的例子和信息也可以阅读 Erlang inets User Guide,和 HTTP Client 章节。

原文链接: https://www.proctor-it.com/erlang-thursday-httpc-request-1-and-httpc-request-4/