扭曲的位置标头重定向
Posted
技术标签:
【中文标题】扭曲的位置标头重定向【英文标题】:twisted location header redirect 【发布时间】:2012-10-16 02:40:41 【问题描述】:从Resource
中的Resource
的render_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()
或者只是使用web
twistd插件,放入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 应用
在powershell中使用Invoke-WebRequest重定向URL时如何获取位置标头