Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cookies HTTPoison饼干_Cookies_Elixir - Fatal编程技术网

Cookies HTTPoison饼干

Cookies HTTPoison饼干,cookies,elixir,Cookies,Elixir,我想浏览一个网站。我想浏览的网站没有API 我想做的是(在Python中): 当尝试使用HTTPoison执行相同操作时,该网站的响应是“请在浏览器中启用会话cookies!”。长生不老药代码: HTTPoison.post "http://demo.ilias.de/login.php", "{\"username\":\"benjamin\", \"password\":\"iliasdemo\"}" 我想问题在于饼干 UPD#1。似乎并不是所有cookie都被保存,因为我在浏览器和

我想浏览一个网站。我想浏览的网站没有API

我想做的是(在Python中):

当尝试使用HTTPoison执行相同操作时,该网站的响应是“请在浏览器中启用会话cookies!”。长生不老药代码:

HTTPoison.post "http://demo.ilias.de/login.php", 
  "{\"username\":\"benjamin\", \"password\":\"iliasdemo\"}"
我想问题在于饼干


UPD#1。似乎并不是所有cookie都被保存,因为我在浏览器和上面Python代码的响应中都看到了
:hackney.cookies(headers)
headers
来自
%HTTPoison.Response{headers:headers}
)并没有输出一些cookies(例如
authchallenge
)。哈克尼真的没有发布任何东西吗?

我也有类似的问题:

我向服务器api发出一个GET请求,它在同一位置用301重定向和一个带有sessionId的“Set Cookie”头进行响应。如果您遵循重定向而不发送回它们的cookie,则它们将以相同的重定向和新的SessionId cookie进行响应。如果你不把饼干还给他们,这种动机还会继续下去。另一方面,如果你把他们的cookie发回,他们会回复200状态码和你询问的数据

问题在于hackney,因此HTTPoison无法遵循这种情况。 它实际上有一个:follow_redirect选项,当设置该选项时,它会跟随重定向,但在抓取cookie并在重定向之间发送回cookie方面存在不足

我尝试过的所有浏览器(firefox、chrome、IE)都可以通过这个场景。 Python和wget也完成了这项工作

总之,简而言之,我为我的案例编写了一个变通方法,它可能会给其他有类似问题的人一些想法:

defmodule GVHTTP do
  defmacro __using__(_) do
    quote do
      use HTTPoison.Base

      def cookies_from_resp_headers(recv_headers) when is_list(recv_headers) do
        List.foldl(recv_headers, [], fn
          {"Set-Cookie", c}, acc -> [c|acc]
          _, acc -> acc
        end)
        |> Enum.map(fn(raw_cookie) ->
            :hackney_cookie.parse_cookie(raw_cookie)
            |> (fn
                  [{cookie_name, cookie_value} | cookie_opts] ->
                    { cookie_name, cookie_value,
                      cookie_opts
                    }
                  _error ->
                    nil
                end).()
        end)
        |> Enum.filter(fn
          nil -> false
          _ -> true
        end)
      end

      def to_request_cookie(cookies) do
        cookies
        |> Enum.map(fn({ cookie_name, cookie_value, _cookie_opts}) ->
            cookie_name <> "=" <> cookie_value
          end)
        |> Enum.join("; ")
        |> (&("" == &1 && [] || [&1])).() # "" => [], "foo1=abc" => ["foo1=abc"]
      end

      def get(url, headers \\ [], options \\ []) do
        case options[:follow_redirect] do
          true ->
            hackney_options = case options[:max_redirect] do
              0 -> options # allow HTTPoison to handle the case of max_redirect overflow error
              _ -> Keyword.drop(options, [:follow_redirect, :max_redirect])
            end
            case request(:get, url, "", headers, hackney_options) do
              {:ok, %HTTPoison.Response{status_code: code, headers: recv_headers}} when code in [301, 302, 307] ->
                {_, location} = List.keyfind(recv_headers, "Location", 0)
                req_cookie =
                  cookies_from_resp_headers(recv_headers)
                  |> to_request_cookie()

                new_options =
                  options
                    |> Keyword.put(:max_redirect, (options[:max_redirect] || 5) - 1)
                    |> Keyword.put(:hackney, [cookie:
                        [options[:hackney][:cookie]|req_cookie]
                        |> List.delete(nil)
                        |> Enum.join("; ")
                      ]) # add any new cookies along with the previous ones to the request
                get(location, headers, new_options)
              resp ->
                resp
            end
          _ ->
            request(:get, url, "", headers, options)
        end
      end

    end # quote end
  end  # __using__ end
end
defmodule GVHTTP-do
定义宏\uuuuuu使用\uuuu(\uu)do
引述
使用HTTPoison.Base
当列表(recv_头)执行时,从_resp_头(recv_头)定义cookies_
List.foldl(recv_头,[],fn
{“设置Cookie”,c},acc->[c|acc]
_,acc->acc
(完)
|>枚举映射(fn(原始cookie)->
:hackney_cookie.parse_cookie(原始_cookie)
|>(fn
[{cookie\u name,cookie\u value}cookie\u opts]>
{cookie\u名称,cookie\u值,
cookie_选项
}
_错误->
无
(完)
(完)
|>枚举过滤器(fn
零->假
_->对
(完)
结束
def to_request_cookie(cookies)do
饼干
|>map(fn({cookie\u name,cookie\u value,{cookie\u opts})->
cookie\u名称“=”cookie\u值
(完)
|>枚举连接(“;”)
|>(&(“===&1&&[]| |[&1]))。(&(“=”=>[],“foo1=abc”=>[“foo1=abc”]
结束
def get(url、标题\\[],选项\\[])执行
案例选项[:follow_redirect]do
正确->
hackney_options=案例选项[:max_redirect]do
0->options#允许HTTPoison处理max_重定向溢出错误的情况
_->关键字.drop(选项,[:follow\u redirect,:max\u redirect])
结束
案例请求(:get、url、“、标题、hackney_选项)do
{:ok,%HTTPoison.Response{status_code:code,headers:recv_headers}}当代码在[301,302,307]中时>
{uu,location}=List.keyfind(recv_头,“location”,0)
需要饼干=
cookies\u来自\u resp\u标头(recv\u标头)
|>请求cookie()的步骤
新选项=
选择权
|>关键字.put(:max_redirect,(选项[:max_redirect]| 5)-1)
|>关键字.put(:hackney,[cookie:
[options[:hackney][:cookie]| req_cookie]
|>列表。删除(无)
|>枚举连接(“;”)
])#在请求中添加任何新cookie以及以前的cookie
获取(位置、标题、新选项)
响应->
响应
结束
_ ->
请求(:get、url、“、标题、选项)
结束
结束
结束#引用结束
结束#uu使用uuuu结束
结束

我不完全确定,因为我从未直接使用过HTTPoison,但本文第108行对您有帮助吗?@ham sandwich在测试文件中,他们发送了一个cookie。在我提出请求的时候,我没有任何饼干可以发送——我应该以某种方式保存它。我认为,有一种方法可以做到这一点。我只是不知道如何使用它。
defmodule GVHTTP do
  defmacro __using__(_) do
    quote do
      use HTTPoison.Base

      def cookies_from_resp_headers(recv_headers) when is_list(recv_headers) do
        List.foldl(recv_headers, [], fn
          {"Set-Cookie", c}, acc -> [c|acc]
          _, acc -> acc
        end)
        |> Enum.map(fn(raw_cookie) ->
            :hackney_cookie.parse_cookie(raw_cookie)
            |> (fn
                  [{cookie_name, cookie_value} | cookie_opts] ->
                    { cookie_name, cookie_value,
                      cookie_opts
                    }
                  _error ->
                    nil
                end).()
        end)
        |> Enum.filter(fn
          nil -> false
          _ -> true
        end)
      end

      def to_request_cookie(cookies) do
        cookies
        |> Enum.map(fn({ cookie_name, cookie_value, _cookie_opts}) ->
            cookie_name <> "=" <> cookie_value
          end)
        |> Enum.join("; ")
        |> (&("" == &1 && [] || [&1])).() # "" => [], "foo1=abc" => ["foo1=abc"]
      end

      def get(url, headers \\ [], options \\ []) do
        case options[:follow_redirect] do
          true ->
            hackney_options = case options[:max_redirect] do
              0 -> options # allow HTTPoison to handle the case of max_redirect overflow error
              _ -> Keyword.drop(options, [:follow_redirect, :max_redirect])
            end
            case request(:get, url, "", headers, hackney_options) do
              {:ok, %HTTPoison.Response{status_code: code, headers: recv_headers}} when code in [301, 302, 307] ->
                {_, location} = List.keyfind(recv_headers, "Location", 0)
                req_cookie =
                  cookies_from_resp_headers(recv_headers)
                  |> to_request_cookie()

                new_options =
                  options
                    |> Keyword.put(:max_redirect, (options[:max_redirect] || 5) - 1)
                    |> Keyword.put(:hackney, [cookie:
                        [options[:hackney][:cookie]|req_cookie]
                        |> List.delete(nil)
                        |> Enum.join("; ")
                      ]) # add any new cookies along with the previous ones to the request
                get(location, headers, new_options)
              resp ->
                resp
            end
          _ ->
            request(:get, url, "", headers, options)
        end
      end

    end # quote end
  end  # __using__ end
end