20

httpc:requestリモートサービスにデータを投稿するために使用しています。投稿は機能していますが、投稿の body() 内のデータは、リモート サービスによって解析されたときに投稿が失敗する原因となる URL エンコードなしでそのまま送信されます。

CGI.escapeこの目的のために Ruby に似た Erlang の関数はありますか?

4

8 に答える 8

24

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

于 2009-02-01T17:49:02.217 に答える
10

少なくとも R15 には、仕事をする http_uri:encode/1があります。また、'=' を %3D ではなく %3d に変換する edoc_lib:escape_uri を使用することはお勧めしません。これにより、問題が発生しました。

于 2012-04-27T14:26:15.037 に答える
9

ここでYAWS url_encode および url_decode ルーチンを見つけることができます

コメントは、すべての句読点文字のエンコードが 100% 完了していないことを示していますが、かなり単純です。

于 2008-09-23T07:17:03.833 に答える
7

これは、仕事をする簡単な関数です。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"}])}
             ,[],[]).
于 2010-08-17T16:16:46.560 に答える
6

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: ƹÈ
于 2012-09-28T23:15:26.223 に答える
4

私自身の質問に答えるために... ibrowse でこのライブラリを見つけました!

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 を使用できると思います。

于 2008-09-22T11:07:10.450 に答える
1

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 >= $0, 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 == $_ ->
    [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 ->
    [$0 + 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 以降でのみ機能することに注意してください。

使用例は次のとおりです。

9> httpc:request("http://httpbin.org/get?q=" ++ mylib_app:escape_uri("☺")).
{ok,{{"HTTP/1.1",200,"OK"},
     [{"connection","keep-alive"},
      {"date","Sat, 09 Nov 2019 21:51:54 GMT"},
      {"server","nginx"},
      {"content-length","178"},
      {"content-type","application/json"},
      {"access-control-allow-credentials","true"},
      {"access-control-allow-origin","*"},
      {"referrer-policy","no-referrer-when-downgrade"},
      {"x-content-type-options","nosniff"},
      {"x-frame-options","DENY"},
      {"x-xss-protection","1; mode=block"}],
     "{\n  \"args\": {\n    \"q\": \"\\u263a\"\n  }, \n  \"headers\": {\n    \"Host\": \"httpbin.org\"\n  }, \n  \"origin\": \"11.111.111.111, 11.111.111.111\", \n  \"url\": \"https://httpbin.org/get?q=\\u263a\"\n}\n"}}

クエリ パラメータをエスケープしてリクエストを送信すると、正しい Unicode コードポイントが返されることがわかります。

于 2010-09-18T20:11:31.207 に答える
0

私の知る限り、標準ライブラリには URL エンコーダーはありません。次のコードは、YAWS または他の Erlang Web サーバーの 1 つから「借りた」ものだと思います。

% 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,$&,[])).

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 -> $0 + C;
hexdigit(C) when C < 16 -> $A + (C - 10).
于 2008-09-22T10:54:43.587 に答える