سؤال

أنا أستخدم erlang http:request لنشر بعض البيانات إلى خدمة بعيدة.لدي المنشور يعمل ولكن البيانات الموجودة في النص () للمنشور تأتي كما هي، دون أي تشفير لعنوان URL مما يتسبب في فشل المنشور عند تحليله بواسطة الخدمة عن بعد.

هل هناك وظيفة في Erlang مشابهة لـ CGI.escape في Ruby لهذا الغرض؟

هل كانت مفيدة؟

المحلول

يمكنك أن تجد هنا إجراءات YAWS url_encode وurl_decode

إنها واضحة إلى حد ما، على الرغم من أن التعليقات تشير إلى أن التشفير ليس كاملاً بنسبة 100% لجميع أحرف الترقيم.

نصائح أخرى

لقد واجهت نقص هذه الميزة في وحدات HTTP أيضًا.

اتضح أن هذه الوظيفة متاحة بالفعل في توزيعة erlang، كل ما عليك فعله هو البحث بعناية كافية.

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

هذا يتصرف مثل 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"}])}
             ,[],[]).

للإجابة على سؤالي...لقد وجدت هذا الكتاب في التصفح!

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()

يقوم عنوان URL بتشفير سلسلة بناءً على RFC 1738.إرجاع قائمة مسطحة.

أعتقد أنه يمكنني استخدام هذا للقيام بالترميز وما زلت أستخدم http:

إذا احتاج شخص ما إلى تشفير uri الذي يعمل مع utf-8 في erlang:

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 >= $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 أو الأحدث.

AFAIK لا يوجد برنامج تشفير URL في المكتبات القياسية.أعتقد أنني "استعرت" الكود التالي من YAWS أو ربما أحد خوادم الويب Erlang الأخرى:

% 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).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top