扭曲的位置标头重定向

Posted

技术标签:

【中文标题】扭曲的位置标头重定向【英文标题】:twisted location header redirect 【发布时间】:2012-10-16 02:40:41 【问题描述】:

Resource 中的Resourcerender_GET 方法twisted,是否可以完全重定向到不同的url(托管在其他地方)

request.redirect(url) 似乎没有做任何事情,twisted.web.util.Redirect 也没有做任何事情

php 中的等价物是,

header('location:'.$url);

编辑

这是我正在运行的代码

from twisted.web import server, resource
from twisted.internet import reactor

class Simple(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        request.redirect("www.google.com")
        request.finish()

site = server.Site(Simple())
reactor.listenTCP(8080, site)
reactor.run()

【问题讨论】:

请发布完整示例。您引用的两种方法都可以正常工作,很明显您以某种方式误用了它们,但我们不知道是怎么回事,因为您没有包含任何代码。 @Glyph 我已将代码添加到问题中。我尝试了几件事,但不确定其中任何一个是正确的。我认为答案很简单,不需要示例。 【参考方案1】:

我在另一张海报的帮助下最终解决了这个问题,request.finish(),重定向包括http:// 并返回NOT_DONE_YET

from twisted.web import server, resource
from twisted.internet import reactor

class Simple(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        request.redirect("http://www.google.com")
        request.finish()
        return server.NOT_DONE_YET

site = server.Site(Simple())
reactor.listenTCP(8080, site)
reactor.run()

【讨论】:

您不需要调用 request.finish() 并返回 server.NOT_DONE_YET。您可以直接返回 ""。 一个观察:如果你使用这个 (finish()+NOT_DONE_YET) 你会遇到上游代理服务器的问题。 nginx 向我返回了“502 Bad Gateway”。我一般用return "",用nginx没问题。所以这似乎不是正确的答案。为什么要将服务器设置为 NOT_DONE_YET 状态也有点奇怪,因为重定向是可以干净地关闭通道的完整回复。 AFAIK 您必须在某个时候手动处理 NOT_DONE_YET 状态,方法是调用 finish() 并返回答案。【参考方案2】:

Location header requires absolute url 例如http://example.com

302 Found 响应代码表明我们应该提供一个简短的超文本注释,其中包含指向新 URI 的超链接。 redirectTo() 正是这样做的:

from twisted.web import server, resource
from twisted.web.util import redirectTo
from twisted.internet import reactor

class HelloResource(resource.Resource):
    isLeaf = True
    
    def render_GET(self, request):
        return redirectTo('http://example.com', request)

reactor.listenTCP(8080, server.Site(HelloResource()))
reactor.run()

或者使用Redirect:

from twisted.web import server
from twisted.web.util import Redirect
from twisted.internet import reactor

reactor.listenTCP(8080, server.Site(Redirect("http://example.com")))
reactor.run()

或者只是使用webtwistd插件,放入redirect.rpy文件:

from twisted.web.util import Redirect

resource = Redirect("http://example.com")

运行:

$ twistd -n web --port tcp:8080:localhost --resource-script redirect.rpy

只是为了演示,下面是redirectTo() 的实现可能的样子:

def redirect_to(url, request):
    request.setResponseCode(302) # Found
    request.setHeader("Location", url)
    request.setHeader("Content-Type", "text/html; charset=UTF-8")
    return """put html with a link to %(url)s here""" % dict(url=url) # body

【讨论】:

【参考方案3】:

您应该能够使用request.redirect(url) 进行重定向,然后调用request.finish()。请确认您拨打的是request.finish()

【讨论】:

如果我调用finish,我会得到exceptions.RuntimeError: Request.write called on a request after Request.finish was called. .redirect 方法似乎只能在本地重定向:http://localhost:8080/www.google.com 而我想去www.google.com 为什么在request.redirect()request.finish() 之后调用request.write()?在标头中处理重定向后,响应中的所有内容都将被忽略。 我没有,方法返回后必须做的事情 好的,我参考了twistedmatrix.com/documents/8.2.0/api/… 的文档。看起来这个方法应该返回一个字符串。您可以通过按照文档输入return twisted.web.server.NOT_DONE_YET 来避免这种期望。但是,请注意,对于这个极其简化的网络服务器框架来说,这似乎有点过于复杂。

以上是关于扭曲的位置标头重定向的主要内容,如果未能解决你的问题,请参考以下文章

从 Chrome 重定向到带有位置标头的 302 后被阻止的 Android 应用

使用浏览器应发送到重定向位置的 HTTP 重定向发送信息?

在powershell中使用Invoke-WebRequest重定向URL时如何获取位置标头

标头重定向的安全性如何?可以绕过吗?

php - 标头位置重定向:https 到 https,http 到 http

使用 urllib2.urlopen 时如何访问包含重定向的原始响应标头