如何在Google App Engine中重定向所有URL

21

我该如何配置app.yaml文件以将所有 URL 重定向到另一个 URL?例如,我想要http://example.appspot.com/hellohttp://example.appspot.com/hello28928723都重定向到http://example.com

目前我只提供静态文件。以下是我的app.yaml文件:

application: testapp
version: 1
runtime: python
api_version: 1

handlers:
- url: (.*)/
  static_files: static\1/index.html
  upload: static/index.html

- url: /
  static_dir: static
7个回答

40

Webapp2自带重定向处理程序。

不需要自己编写处理程序,webapp2已经自带了一个。

application = webapp2.WSGIApplication([
    webapp2.Route('/hello', webapp2.RedirectHandler, defaults={'_uri':'http://example.com'}),
    webapp2.Route('/hello28928723', webapp2.RedirectHandler, defaults={'_uri':'http://example.com'}),
], debug=False)

_uri参数是RedirectHandler类用来定义目标位置的。我花了很多时间在谷歌上查找相关文档,但它在我的应用程序中运行得非常完美。

我假设你已经知道这一点,但你需要将你的全捕获路由从以下代码更改:

- url: /
  static_dir: static

翻译内容如下:

转换为(python27版本):

To (python27 version):

- url: /.*
  script: main.application

或:(适用于 Python 2.7 以下版本)

- url: /.*
  script: main.py

main.py 是包含请求处理器和路由的文件。

注意:由于静态文件的性质,在GAE上没有纯静态的方式来处理重定向。基本上,只有app.yaml是无法完成重定向的。


2
这个处理程序能够处理get/post等请求... 这基本上是在GAE中执行301(永久)重定向的“正确”方法。 - Evan Plaice
需要注意的是,很明显,应用引擎不支持重定向到静态文件/目录。我无法让重定向正常工作。我的日志中一直出现这些错误:“处理程序引用的文件未找到:main.app”。最后,我发现了这篇文章,证实处理程序无法访问静态文件:http://stackoverflow.com/questions/8734040/google-app-engine-static-pages-python-2-5-directories-etc。 - Stephen Kaiser
@StephenKaiser 从技术上讲,这不是一个重定向,但您可以在app.yaml中定义一个新路由,将旧的URI指向新的URI。由于架构和静态文件处理方式的原因,无法在静态文件上定义实际的301/302重定向。 - Evan Plaice
我认为hello28928723只是一个例子,他想要重定向所有请求。 - Jonny
@Jonny 在GAE上处理静态和非静态文件的方式有很大的区别。您可以在上面的列表中添加一个非静态句柄,专门用于捕获重定向。无论哪种方式,都很重要了解为什么在GAE中处理静态文件与非静态文件不同。App.yaml基本上是一个反向代理的指令集,其中所有静态文件实际上都存储在静态文件缓存中,与非静态文件分开存储。在达到http服务器之前(即不是静态缓存),不可能进行302/301重定向。 - Evan Plaice
我尝试了你的第一个例子RedirectHandler,但是出现了错误File "/usr/local/lib/python2.7/dist-packages/webapp2_extras/routes.py", line 157, in __init__ setattr(route, self._attr, prefix + getattr(route, self._attr)) TypeError: cannot concatenate 'str' and 'type' objects - Christian

9

您所需要的是(将app-id, http://example.com 替换为实际内容):

  • app.yaml:

    application: app-id
    version: 1
    runtime: python27
    api_version: 1
    threadsafe: false
    
    handlers:
    - url: /.*
      script: main.py
    
  • main.py:

    from google.appengine.ext import webapp
    from google.appengine.ext.webapp.util import run_wsgi_app
    
    class AllHandler(webapp.RequestHandler):
        def get(self):
            self.redirect("http://example.com", True)
    
    application = webapp.WSGIApplication([('/.*', AllHandler)])
    
    def main():
        run_wsgi_app(application)
    
    if __name__ == "__main__":
        main()
    

建议在app.yaml处理程序中添加"secure: optional",以使https正常工作。 - Jay Lee
如果未提供“secure: optional”,则默认为可选安全性(https://cloud.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Secure_URLs)。 - qix

5
您可以使用Python处理程序轻松重定向所有请求。例如:
class FormHandler(webapp.RequestHandler):
  def post(self):
    if processFormData(self.request):
      self.redirect("http://example.com")

10
这个答案不完整 - 单凭那段代码片段是不足以重定向请求的。另外,那么 GET 请求呢? - Brian Leathem
1
@BrianLeathem 刚刚发布了一个完整的示例 - feklee

5
如果您想使用仅限静态文件的方式进行“重定向”,请执行以下操作:
在app.yaml中,将以下内容作为捕获所有内容的方法放置在文件末尾:
-   url: /.*
    static_files: root/redirect.html
    upload: root/redirect.html

然后在root/redirect.html文件中,添加以下内容:
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="refresh" content="0;URL=/" />
        <script>
            location.replace("/");
        </script>
    </head>
    <body></body>
</html>

这个示例将所有未知的URL重定向到根目录(即 / )。如果你想要另一个URL,只需在适当的位置替换 http://example.com


4
这里有一个Python脚本,可以实现重定向:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
  def get(self, path):
    self.redirect("http://example.com", permanent=True)
  def head(self, path):
    self.redirect("http://example.com", permanent=True)

application = webapp.WSGIApplication(
            [
                (r'^(.*)', MainPage)
            ])

def main():
   run_wsgi_app(application)

if __name__ == "__main__":
    main()

请注意,@Evan Plaice提供的webapp2答案可行,但我卡在了旧的数据存储上,无法使用Python 2.7。 - Brian Leathem
如果发布的解决方案向后兼容Web应用程序,则加1分。 - Evan Plaice

-1

在之前的答案中提到的webapp2的重定向处理程序(webapp2.RedirectHandler)对于POST请求不起作用,因为它不包含一个post方法(请参见https://github.com/GoogleCloudPlatform/webapp2/blob/master/webapp2.py),因此如果涉及到POST请求,您需要自己编写Python处理程序。可以使用以下类似代码:

import webapp2

class MainPage(webapp2.RequestHandler):


    def post(self):
        self.redirect('http://example.com')


application = webapp2.WSGIApplication([
('/.*', MainPage)
], debug=False)

-1

提醒一下,"官方文档"的链接已经失效了。:-/ 不过我找到了一个似乎涵盖了这个问题的链接:https://webapp2.readthedocs.io/en/latest/guide/routing.html - jetsetter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接