Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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
Python2.7-重定向处理程序isn';t在re-direct上传递参数_Python_Python 2.7_Urllib2_Urllib - Fatal编程技术网

Python2.7-重定向处理程序isn';t在re-direct上传递参数

Python2.7-重定向处理程序isn';t在re-direct上传递参数,python,python-2.7,urllib2,urllib,Python,Python 2.7,Urllib2,Urllib,我在一个可以移动的站点上找到了一个url,当移动端点时,我需要重新应用POST/GET参数。我缺少什么来确保该处理程序执行此操作 class RedirectHandler(urllib2.HTTPRedirectHandler): def http_error_301(self, req, fp, code, msg, headers): result = urllib2.HTTPRedirectHandler.http_error_301( s

我在一个可以移动的站点上找到了一个url,当移动端点时,我需要重新应用POST/GET参数。我缺少什么来确保该处理程序执行此操作

class RedirectHandler(urllib2.HTTPRedirectHandler):


  def http_error_301(self, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_301(
            self, req, fp, code, msg, headers)
        result.status = code
        return result

    def http_error_302(self, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_302(
            self, req, fp, code, msg, headers)
        result.status = code
        return result
当我通过fiddler观察流量时,我注意到用于身份验证的令牌被丢弃

(请注意,我无法使用此解决方案的请求,它只能是标准库)


谢谢

关于HTTP 1.0和1.1状态代码302、303和307的故事有点复杂。基本上,您可以看到预期和行为(您也可以查看更长的描述):

此方法的默认实现并不严格遵循,即未经用户确认,不得自动重定向对
POST
请求的301和302响应。实际上,浏览器确实允许自动重定向这些响应,将
POST
更改为
GET
,默认实现再现了这种行为

你走的路是对的,但覆盖了错误的方法。以下是
urllib2.HTTPRedirectHandler.redirect\u请求的源代码:

def redirect_request(self, req, fp, code, msg, headers, newurl):
    """Return a Request or None in response to a redirect.
    ...
    Return None if you can't but another Handler might.
    """
    m = req.get_method()
    if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
        or code in (301, 302, 303) and m == "POST"):
        # ...
        newurl = newurl.replace(' ', '%20')
        newheaders = dict((k,v) for k,v in req.headers.items()
                          if k.lower() not in ("content-length", "content-type")
                         )
        return Request(newurl,
                       headers=newheaders,
                       origin_req_host=req.get_origin_req_host(),
                       unverifiable=True)
    else:
        raise HTTPError(req.get_full_url(), code, msg, headers, fp)
这里有几个观察结果。它不传递
数据
,因此新请求是
GET
。它过滤掉
内容长度
内容类型
标题,这是正确的
帖子所必需的。如果事实上,在我的示例中,
req.headers
是一个空的dict,那么我求助于
req.header\u items()
(请参见
unrecorded\u hdrs
)。此外,is不处理
POST
和307重定向

下面是POST和302重定向的正确重定向程序处理程序实现。这里还有完整的CherryPy模拟(请在之前安装CherryPy)


你的饼干在哪里?(或您的会话信息)@SDilmac所以您认为cookie处理程序可以解决此问题?是的!所有使用cookie cos的web服务都无法保存访问者的所有操作。@SDilmac我在开场白中添加了cookiejar和处理程序,并且响应服务器没有返回cookie,因此我猜服务器不会返回cookie。我甚至尝试在网络浏览器中做同样的事情(观察fiddler中的流量),但没有返回身份验证。我的猜测是webbrowser将表单参数从一个url保存到另一个url。我需要在302重定向上捕获原始请求中的参数/数据,然后将它们推送到新请求。我试图创建一个新的请求对象,但这会引发一个错误。试试这个。浏览器、服务器、客户端、ssl等等。。你想要在一个包上抓取一些头,但是如果触碰它就会被破坏。需要先克隆才能重用。或者将您的计算机设置为网关!我希望能帮上忙。谢谢你的回复,我会测试一下并回复你!
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import urllib2
from urllib2 import HTTPRedirectHandler, Request

import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}


class RedirectHandler(HTTPRedirectHandler):

    def redirect_request(self, req, fp, code, msg, headers, newurl):
      if code == 302 and req.get_method() == 'POST':
        return Request(newurl, headers=dict(req.header_items()), data=req.data,
          origin_req_host=req.get_origin_req_host(), unverifiable=True)
      else:
        return HTTPRedirectHandler.redirect_request(self, req, fp, code, msg, 
          headers, newurl)


class App:

  @cherrypy.expose
  def index(self):
    opener = urllib2.build_opener(RedirectHandler())
    return opener.open('http://localhost:8080/redirect', data='foo=bar')

  @cherrypy.expose
  def redirect(self, **kwargs):
    print('Before redirect {0}'.format(kwargs))
    raise cherrypy.HTTPRedirect('/target', 302)

  @cherrypy.expose
  def target(self, **kwargs):
    return 'Target received {0} {1}'.format(cherrypy.request.method, kwargs)


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)