我正在使用erlang http:request将一些数据发布到远程服务。我有帖子工作,但帖子的body()中的数据是按原样进行的,没有任何url编码导致帖子在远程服务解析时失败。

在Erlang中是否有一个与Ruby中的CGI.escape类似的函数用于此目的?

有帮助吗?

解决方案

你可以在这里找到 YAWS url_encode和url_decode例程

它们相当简单,但注释表明所有标点字符的编码不是100%完整。

其他提示

我在HTTP模块中也遇到了这个功能。

事实证明,这个功能实际上在erlang发行版中可用,你只需要看起来很难。

> edoc_lib:escape_uri("luca+more@here.com").
"luca%2bmore%40here.com"

这与Ruby中的CGI.escape类似,还有URI.escape,其行为略有不同:

> CGI.escape("luca+more@here.com")
 => "luca%2Bmore%40here.com" 
> URI.escape("luca+more@here.com")
 => "luca+more@here.com" 

edoc_lib

至少在R15中有 http_uri:encode / 1 做哪个工作。我也不建议使用edoc_lib:escape_uri将'='转换为%3d而不是%3D,这会给我带来一些麻烦。

这是一个完成工作的简单功能。它旨在直接使用inets httpc。

%% @doc A function to URL encode form data.
%% @spec url_encode(formdata()).

-spec(url_encode(formdata()) -> string()).
url_encode(Data) ->
    url_encode(Data,"").

url_encode([],Acc) ->
    Acc;

url_encode([{Key,Value}|R],"") ->
    url_encode(R, edoc_lib:escape_uri(Key) ++ "=" ++ edoc_lib:escape_uri(Value));
url_encode([{Key,Value}|R],Acc) ->
    url_encode(R, Acc ++ "&" ++ edoc_lib:escape_uri(Key) ++ "=" ++ edoc_lib:escape_uri(Value)).

使用示例:

httpc:request(post, {"http://localhost:3000/foo", [], 
                    "application/x-www-form-urlencoded",
                    url_encode([{"username", "bob"}, {"password", "123456"}])}
             ,[],[]).

回答我自己的问题......我在ibrowse找到了这个lib!

http://www.erlware .ORG / LIB / 5.6.3 / ibrowse-1.4 / ibrowse_lib.html#url_encode-1

url_encode/1

url_encode(Str) -> UrlEncodedStr

Str = string()
UrlEncodedStr = string()

对基于RFC 1738的字符串进行URL编码。返回一个平面列表。

我想我可以使用它来进行编码并仍然使用http:

如果有人需要编码在erlang中使用utf-8的uri:

https://gist.github.com/3796470

实施例

Eshell V5.9.1  (abort with ^G)

1> c(encode_uri_rfc3986).
{ok,encode_uri_rfc3986}

2> encode_uri_rfc3986:encode("テスト").
"%e3%83%86%e3%82%b9%e3%83%88"

3> edoc_lib:escape_uri("テスト").
"%c3%86%c2%b9%c3%88" # output wrong: ƹÈ

这是一个“叉子”。 edoc_lib:escape_uri函数,它改进了UTF-8支持并且还支持二进制文件。

escape_uri(S) when is_list(S) ->
    escape_uri(unicode:characters_to_binary(S));
escape_uri(<<C:8, Cs/binary>>) when C >= $a, C =< $z ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C >= $A, C =< $Z ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C >= <*>, C =< $9 ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == $. ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == $- ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == 

这是一个“叉子”。 edoc_lib:escape_uri函数,它改进了UTF-8支持并且还支持二进制文件。

<*>

请注意,由于使用了unicode:characters_to_binary,它只能在R13或更新版本中使用。

-> [C] ++ escape_uri(Cs); escape_uri(<<C:8, Cs/binary>>) -> escape_byte(C) ++ escape_uri(Cs); escape_uri(<<>>) -> "". escape_byte(C) -> "%" ++ hex_octet(C). hex_octet(N) when N =< 9 -> [<*> + N]; hex_octet(N) when N > 15 -> hex_octet(N bsr 4) ++ hex_octet(N band 15); hex_octet(N) -> [N - 10 + $a].

请注意,由于使用了unicode:characters_to_binary,它只能在R13或更新版本中使用。

AFAIK标准库中没有URL编码器。想想我从YAWS或者其他Erlang Web服务器中借用了以下代码:

% Utility function to convert a 'form' of name-value pairs into a URL encoded
% content string.

urlencode(Form) ->
    RevPairs = lists:foldl(fun({K,V},Acc) -> [[quote_plus(K),$=,quote_plus(V)] | Acc] end, [],Form),
    lists:flatten(revjoin(RevPairs,<*>amp;,[])).

quote_plus(Atom) when is_atom(Atom) ->
    quote_plus(atom_to_list(Atom));

quote_plus(Int) when is_integer(Int) ->
    quote_plus(integer_to_list(Int));

quote_plus(String) ->
    quote_plus(String, []).

quote_plus([], Acc) ->
    lists:reverse(Acc);

quote_plus([C | Rest], Acc) when ?QS_SAFE(C) ->
    quote_plus(Rest, [C | Acc]);

quote_plus([$\s | Rest], Acc) ->
    quote_plus(Rest, [<*> | Acc]);

quote_plus([C | Rest], Acc) ->
    <<Hi:4, Lo:4>> = <<C>>,
    quote_plus(Rest, [hexdigit(Lo), hexdigit(Hi), ?PERCENT | Acc]).

revjoin([], _Separator, Acc) ->
    Acc;

revjoin([S | Rest],Separator,[]) ->
    revjoin(Rest,Separator,[S]);

revjoin([S | Rest],Separator,Acc) ->
    revjoin(Rest,Separator,[S,Separator | Acc]).

hexdigit(C) when C < 10 -> <*> + C;
hexdigit(C) when C < 16 -> $A + (C - 10).
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top