檢視原始碼 URI (Elixir v1.16.2)

處理 URI 的公用程式。

此模組提供用於處理 URI 的函式(例如,剖析 URI 或編碼查詢字串)。此模組中的函式根據 RFC 3986 實作。

摘要

類型

authority() 已棄用
t()

函式

URI 結構。

path 附加至指定的 uri

query 附加至指定的 uri

檢查 character 是否為 URI 中的保留字元。

檢查 character 是否允許在 URI 中不經跳脫。

檢查 character 是否為 URI 中的非保留字元。

百分比跳脫 URI。

query 解碼成一個映射。

string 解碼為「x-www-form-urlencoded」。

傳回指定 scheme 的預設埠號。

註冊指定 scheme 的預設 port

百分比編碼 string 中所有需要跳脫的字元。

使用 編碼可列舉 編碼成查詢字串。

字串 編碼為「x-www-form-urlencoded」。

合併兩個 URI。

從 URI 或字串建立新的 URI 結構。

類似於 new/1,但如果給定無效的字串,則會引發 URI.Error

將 URI 解析成其組成部分,而不會進一步驗證。

傳回一個串流,其中包含代表給定 查詢 中的鍵值對的兩個元素元組。

傳回給定 URI 結構 的字串表示形式。

類型

這個不透明已過時。權限欄位已過時。
@opaque authority()
@type t() :: %URI{
  authority: authority(),
  fragment: nil | binary(),
  host: nil | binary(),
  path: nil | binary(),
  port: nil | :inet.port_number(),
  query: nil | binary(),
  scheme: nil | binary(),
  userinfo: nil | binary()
}

函數

URI 結構。

定義這些欄位以符合下列 URI 表示形式(欄位名稱在括號中)

[scheme]://[userinfo]@[host]:[port][path]?[query]#[fragment]

請注意,權限欄位已過時。 parse/1 仍會填入它以維持向後相容性,但您通常應避免設定或取得它。

連結到這個函數

append_path(uri, path)

檢視原始碼 (自 1.15.0 起)
@spec append_path(t(), String.t()) :: t()

path 附加至指定的 uri

路徑必須以 / 開頭,且不能包含其他 URL 組成部分,例如片段或查詢字串。此函數進一步假設路徑有效,且不包含查詢字串或片段部分。

範例

iex> URI.append_path(URI.parse("http://example.com/foo/?x=1"), "/my-path") |> URI.to_string()
"http://example.com/foo/my-path?x=1"

iex> URI.append_path(URI.parse("http://example.com"), "my-path")
** (ArgumentError) path must start with "/", got: "my-path"
連結到這個函數

append_query(uri, query)

檢視原始碼 (自 1.14.0 起)
@spec append_query(t(), binary()) :: t()

query 附加至指定的 uri

給定的 查詢 沒有自動編碼,請使用 encode/2encode_www_form/1

範例

iex> URI.append_query(URI.parse("http://example.com/"), "x=1") |> URI.to_string()
"http://example.com/?x=1"

iex> URI.append_query(URI.parse("http://example.com/?x=1"), "y=2") |> URI.to_string()
"http://example.com/?x=1&y=2"

iex> URI.append_query(URI.parse("http://example.com/?x=1"), "x=2") |> URI.to_string()
"http://example.com/?x=1&x=2"
@spec char_reserved?(byte()) :: boolean()

檢查 character 是否為 URI 中的保留字元。

RFC 3986 第 2.2 節 所述,保留以下字元::/?#[]@!$&'()*+,;=

範例

iex> URI.char_reserved?(?+)
true
@spec char_unescaped?(byte()) :: boolean()

檢查 character 是否允許在 URI 中不經跳脫。

這是 URI.encode/2 使用的預設值,其中 保留字元非保留字元 都保持未跳脫。

範例

iex> URI.char_unescaped?(?{)
false
連結到這個函數

char_unreserved?(character)

檢視原始碼
@spec char_unreserved?(byte()) :: boolean()

檢查 character 是否為 URI 中的非保留字元。

RFC 3986, 第 2.3 節 所述,下列字元為非保留字元

  • 字母數字字元:A-Za-z0-9
  • ~, _, -, .

範例

iex> URI.char_unreserved?(?_)
true
@spec decode(binary()) :: binary()

百分比跳脫 URI。

範例

iex> URI.decode("https%3A%2F%2Felixir-lang.org")
"https://elixir.dev.org.tw"
連結到這個函數

decode_query(query, map \\ %{}, encoding \\ :www_form)

檢視原始碼
@spec decode_query(binary(), %{optional(binary()) => binary()}, :rfc3986 | :www_form) ::
  %{
    optional(binary()) => binary()
  }

query 解碼成一個映射。

給定一個格式為 key1=value1&key2=value2... 的查詢字串,此函式會將每個查詢字串中的金鑰值對插入給定的 map 中作為一個項目。結果 map 中的金鑰和值將是二進位。金鑰和值將會百分比解跳脫。

你可以指定下列 encoding 選項之一

  • :www_form - (預設值,自 v1.12.0 起) 金鑰和值會根據 decode_www_form/1 解碼。這是瀏覽器通常在查詢字串和表單資料上使用的格式。它會將「+」解碼為「 」。

  • :rfc3986 - (自 v1.12.0 起) 金鑰和值會根據 decode/1 解碼。結果與 :www_form 相同,但會將「+」保留原樣,符合 RFC 3986

編碼預設為 :www_form 以維持向後相容性。

如果你想手動迭代每個值,請使用 query_decoder/1

範例

iex> URI.decode_query("foo=1&bar=2")
%{"bar" => "2", "foo" => "1"}

iex> URI.decode_query("percent=oh+yes%21", %{"starting" => "map"})
%{"percent" => "oh yes!", "starting" => "map"}

iex> URI.decode_query("percent=oh+yes%21", %{}, :rfc3986)
%{"percent" => "oh+yes!"}
@spec decode_www_form(binary()) :: binary()

string 解碼為「x-www-form-urlencoded」。

請注意「x-www-form-urlencoded」未指定為 RFC 3986 的一部分。然而,這是瀏覽器編碼查詢字串和表單資料的常用格式。

範例

iex> URI.decode_www_form("%3Call+in%2F")
"<all in/"
@spec default_port(binary()) :: nil | non_neg_integer()

傳回指定 scheme 的預設埠號。

如果 URI 模組不知道該架構,此函式會傳回 nil。任何架構的預設埠都可透過 default_port/2 全域設定。

範例

iex> URI.default_port("ftp")
21

iex> URI.default_port("ponzi")
nil
@spec default_port(binary(), non_neg_integer()) :: :ok

註冊指定 scheme 的預設 port

呼叫此函式後,default_port/1 會傳回 port 給定 scheme。請注意,此函式會變更給定 scheme 的預設埠號,全域性地,表示對每個應用程式而言。

建議在應用程式的啟動回呼中呼叫此函式,以防您想要註冊新的 URI。

連結到這個函數

encode(string, predicate \\ &char_unescaped?/1)

檢視原始碼
@spec encode(binary(), (byte() -> as_boolean(term()))) :: binary()

百分比編碼 string 中所有需要跳脫的字元。

預設情況下,此函式會對整個 URI 進行跳脫,因此它會跳脫所有不屬於 URI 規範的字元。保留字元(例如 :/)或未保留字元(例如字母和數字)不會被跳脫。

由於 URI 的不同元件需要不同的跳脫規則,因此此函式也接受 predicate 函式作為選用引數。如果傳遞,此函式會以 string 中的每個位元組作為引數呼叫,並在給定的位元組應保持原樣時傳回真值(任何值,除了 falsenil),或在字元應被跳脫時傳回假值(falsenil)。預設為 URI.char_unescaped?/1

如果您有興趣也跳脫保留字元,請參閱 encode_www_form/1

範例

iex> URI.encode("ftp://s-ite.tld/?value=put it+й")
"ftp://s-ite.tld/?value=put%20it+%D0%B9"

iex> URI.encode("a string", &(&1 != ?i))
"a str%69ng"
連結到這個函數

encode_query(enumerable, encoding \\ :www_form)

檢視原始碼
@spec encode_query(Enumerable.t(), :rfc3986 | :www_form) :: binary()

使用 編碼可列舉 編碼成查詢字串。

採用可列舉為兩元素組元清單(例如,映射或關鍵字清單)的可列舉,並傳回 key1=value1&key2=value2... 形式的字串。

金鑰和值可以是任何實作 String.Chars 協定的項目,但清單例外,清單明確禁止。

您可以指定下列 encoding 策略之一

  • :www_form - (預設,自 v1.12.0 起)金鑰和值會根據 encode_www_form/1 以 URL 編碼。這是瀏覽器在查詢字串和表單資料上通常使用的格式。它將 " " 編碼為 "+”。

  • :rfc3986 - (自 v1.12.0 起)與 :www_form 相同,但它會根據 RFC 3986 將 " " 編碼為 "%20”。如果您在非瀏覽器情況下進行編碼,這是最佳選項,因為將空格編碼為 "+" 可能對 URI 解析器來說模稜兩可。這可能會無意間導致空格被解釋為實際的加號。

編碼預設為 :www_form 以維持向後相容性。

範例

iex> query = %{"foo" => 1, "bar" => 2}
iex> URI.encode_query(query)
"bar=2&foo=1"

iex> query = %{"key" => "value with spaces"}
iex> URI.encode_query(query)
"key=value+with+spaces"

iex> query = %{"key" => "value with spaces"}
iex> URI.encode_query(query, :rfc3986)
"key=value%20with%20spaces"

iex> URI.encode_query(%{key: [:a, :list]})
** (ArgumentError) encode_query/2 values cannot be lists, got: [:a, :list]
@spec encode_www_form(binary()) :: binary()

字串 編碼為「x-www-form-urlencoded」。

請注意「x-www-form-urlencoded」未指定為 RFC 3986 的一部分。然而,這是瀏覽器編碼查詢字串和表單資料的常用格式。

範例

iex> URI.encode_www_form("put: it+й")
"put%3A+it%2B%D0%B9"
@spec merge(t() | binary(), t() | binary()) :: t()

合併兩個 URI。

此函數會根據 RFC 3986 第 5.2 節 將兩個 URI 合併。

範例

iex> URI.merge(URI.parse("http://google.com"), "/query") |> to_string()
"http://google.com/query"

iex> URI.merge("http://example.com", "http://google.com") |> to_string()
"http://google.com"
連結到這個函數

new(uri)

檢視原始碼 (自 1.13.0 起)
@spec new(t() | String.t()) :: {:ok, t()} | {:error, String.t()}

從 URI 或字串建立新的 URI 結構。

如果給定 %URI{} 結構,它會傳回 {:ok, uri}。如果給定字串,它會解析並驗證該字串。如果字串有效,它會傳回 {:ok, uri},否則會傳回 {:error, part},其中包含 URI 的無效部分。如要解析 URI 而無需進一步驗證,請參閱 parse/1

此函數可以解析絕對和相對 URL。你可以檢查 URI 是絕對還是相對,方法是檢查 scheme 欄位是否為 nil

當給定 URI 沒有連接埠時,會使用 URI.default_port/1 為 URI 的 scheme 傳回的值作為 :port 欄位。scheme 也會標準化為小寫。

範例

iex> URI.new("https://elixir.dev.org.tw/")
{:ok, %URI{
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: 443,
  query: nil,
  scheme: "https",
  userinfo: nil
}}

iex> URI.new("//elixir.dev.org.tw/")
{:ok, %URI{
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}}

iex> URI.new("/foo/bar")
{:ok, %URI{
  fragment: nil,
  host: nil,
  path: "/foo/bar",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}}

iex> URI.new("foo/bar")
{:ok, %URI{
  fragment: nil,
  host: nil,
  path: "foo/bar",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}}

iex> URI.new("//[fe80::]/")
{:ok, %URI{
  fragment: nil,
  host: "fe80::",
  path: "/",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}}

iex> URI.new("https:?query")
{:ok, %URI{
  fragment: nil,
  host: nil,
  path: nil,
  port: 443,
  query: "query",
  scheme: "https",
  userinfo: nil
}}

iex> URI.new("/invalid_greater_than_in_path/>")
{:error, ">"}

給定現有的 URI 只會將其包在 tuple 中傳回

iex> {:ok, uri} = URI.new("https://elixir.dev.org.tw/")
iex> URI.new(uri)
{:ok, %URI{
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: 443,
  query: nil,
  scheme: "https",
  userinfo: nil
}}
連結到這個函數

new!(uri)

檢視原始碼 (自 1.13.0 起)
@spec new!(t() | String.t()) :: t()

類似於 new/1,但如果給定無效的字串,則會引發 URI.Error

範例

iex> URI.new!("https://elixir.dev.org.tw/")
%URI{
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: 443,
  query: nil,
  scheme: "https",
  userinfo: nil
}

iex> URI.new!("/invalid_greater_than_in_path/>")
** (URI.Error) cannot parse due to reason invalid_uri: ">"

給定現有的 URI 只會傳回該 URI

iex> uri = URI.new!("https://elixir.dev.org.tw/")
iex> URI.new!(uri)
%URI{
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: 443,
  query: nil,
  scheme: "https",
  userinfo: nil
}
@spec parse(t() | binary()) :: t()

將 URI 解析成其組成部分,而不會進一步驗證。

此函數可以解析絕對和相對 URL。你可以檢查 URI 是絕對還是相對,方法是檢查 scheme 欄位是否為 nil。此外,此函數預期絕對和相對 URI 都格式正確,且不會執行任何驗證。請參閱以下「範例」區段。如果你想在解析後驗證 URI 欄位,請使用 new/1

當給定 URI 沒有連接埠時,會使用 URI.default_port/1 為 URI 的 scheme 傳回的值作為 :port 欄位。scheme 也會標準化為小寫。

如果將 %URI{} 結構傳給此函數,此函數會原封不動地傳回該結構。

:authority 欄位

此函數會設定 :authority 欄位以維持向後相容性,但已不建議使用。

範例

iex> URI.parse("https://elixir.dev.org.tw/")
%URI{
  authority: "elixir-lang.org",
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: 443,
  query: nil,
  scheme: "https",
  userinfo: nil
}

iex> URI.parse("//elixir.dev.org.tw/")
%URI{
  authority: "elixir-lang.org",
  fragment: nil,
  host: "elixir-lang.org",
  path: "/",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}

iex> URI.parse("/foo/bar")
%URI{
  fragment: nil,
  host: nil,
  path: "/foo/bar",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}

iex> URI.parse("foo/bar")
%URI{
  fragment: nil,
  host: nil,
  path: "foo/bar",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}

URI.new/1 相反,此函數會解析格式不佳的 URI,例如

iex> URI.parse("/invalid_greater_than_in_path/>")
%URI{
  fragment: nil,
  host: nil,
  path: "/invalid_greater_than_in_path/>",
  port: nil,
  query: nil,
  scheme: nil,
  userinfo: nil
}

另一個範例是查詢字串中包含括號的 URI。此 URI 會被 parse/1 接受,瀏覽器通常也會接受,但會被 new/1 拒絕。

iex> URI.parse("/?foo[bar]=baz")
%URI{
  fragment: nil,
  host: nil,
  path: "/",
  port: nil,
  query: "foo[bar]=baz",
  scheme: nil,
  userinfo: nil
}
連結到這個函數

查詢_解碼器(查詢, 編碼 \\ :www_form)

檢視原始碼
@spec query_decoder(binary(), :rfc3986 | :www_form) :: Enumerable.t()

傳回一個串流,其中包含代表給定 查詢 中的鍵值對的兩個元素元組。

每個 tuple 中的鍵和值都會是二進制資料,且會取消百分比編碼。

你可以指定下列 encoding 選項之一

  • :www_form - (預設值,自 v1.12.0 起) 金鑰和值會根據 decode_www_form/1 解碼。這是瀏覽器通常在查詢字串和表單資料上使用的格式。它會將「+」解碼為「 」。

  • :rfc3986 - (自 v1.12.0 起) 金鑰和值會根據 decode/1 解碼。結果與 :www_form 相同,但會將「+」保留原樣,符合 RFC 3986

編碼預設為 :www_form 以維持向後相容性。

範例

iex> URI.query_decoder("foo=1&bar=2") |> Enum.to_list()
[{"foo", "1"}, {"bar", "2"}]

iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water+please") |> Enum.to_list()
[{"food", "bread&butter"}, {"drinks", "tap water please"}]

iex> URI.query_decoder("food=bread%26butter&drinks=tap%20water+please", :rfc3986) |> Enum.to_list()
[{"food", "bread&butter"}, {"drinks", "tap water+please"}]
@spec to_string(t()) :: binary()

傳回給定 URI 結構 的字串表示形式。

範例

iex> uri = URI.parse("http://google.com")
iex> URI.to_string(uri)
"http://google.com"

iex> uri = URI.parse("foo://bar.baz")
iex> URI.to_string(uri)
"foo://bar.baz"