zoukankan      html  css  js  c++  java
  • 【Azure 应用服务】Python flask 应用部署在Aure App Service中作为一个子项目时,解决遇见的404 Not Found问题

    问题描述

    在成功的部署Python flask应用到App Service (Windows)后,如果需要把当前项目(如:hiflask)作为一个子项目(子站点),把web.config文件从wwwroot中移动到项目文件夹中。访问时,确遇见了404 Not Found的错误。

     查看flask项目的启动日志,可以看见项目启动已经成功。但是为什么请求一直都是404的问题呢?

    2021-09-10 05:29:58.224796: wfastcgi.py will restart when files in D:homesitewwwroothiflask are changed: .*((.py)|(.config))$
    2021-09-10 05:29:58.240445: wfastcgi.py 3.0.0 initialized

    问题解决

    在搜索 flask return 404问题后,发现是因为 URL前缀(prefixed )的问题。因为当前的flask应用访问路径不再是根目录(/),而是(/hiflask)。 所以需要 flask项目中使用 中间件 来处理 url前缀的问题。

    原文内容为:https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes/36033627#36033627

    You have to do is to write a middleware to make the following changes:

    1. modify PATH_INFO to handle the prefixed url.
    2. modify SCRIPT_NAME to generate the prefixed url.

    Like this:

    class PrefixMiddleware(object):
    
        def __init__(self, app, prefix=''):
            self.app = app
            self.prefix = prefix
    
        def __call__(self, environ, start_response):
    
            if environ['PATH_INFO'].startswith(self.prefix):
                environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
                environ['SCRIPT_NAME'] = self.prefix
                return self.app(environ, start_response)
            else:
                start_response('404', [('Content-Type', 'text/plain')])
                return ["This url does not belong to the app.".encode()]

    Wrap your app with the middleware, like this:

    from flask import Flask, url_for
    
    app = Flask(__name__)
    app.debug = True
    app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/foo')
    
    
    @app.route('/bar')
    def bar():
        return "The URL for this page is {}".format(url_for('bar'))
    
    
    if __name__ == '__main__':
        app.run('0.0.0.0', 9010)

    Visit http://localhost:9010/foo/bar,

    You will get the right result: The URL for this page is /foo/bar

    而在App Service中的解决方式就是添加了 PrefixMiddleware,并指定prefix为 /hiflask 。 附上完成的hiflask/app.py 代码和web.config内容。

    hiflask/app.py

    from flask import Flask
    from datetime import datetime
    from flask import render_template
    
    import re
    
    
    class PrefixMiddleware(object):
        def __init__(self, app, prefix=''):
            self.app = app
            self.prefix = prefix
    
        def __call__(self, environ, start_response):
            if environ['PATH_INFO'].startswith(self.prefix):
                environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
                environ['SCRIPT_NAME'] = self.prefix
                return self.app(environ, start_response)
            else:
                start_response('404', [('Content-Type', 'text/plain')])
                return ["This url does not belong to the app.".encode()]
                
    
    
    #if __name__ =="__name__"
    app = Flask(__name__)
    app.debug = True
    app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/hiflask')
    # @app.route("/")
    # def home():
    #     return "Hello, Flask!"
    
    
    print("flask applicaiton started and running..." +datetime.now().strftime("%m/%d/%Y, %H:%M:%S"))
    
    
    # Replace the existing home function with the one below
    @app.route("/")
    def home():
        return render_template("home.html")
    
    # New functions
    @app.route("/about/")
    def about():
        return render_template("about.html")
    
    @app.route("/contact/")
    def contact():
        return render_template("contact.html")
    
    @app.route("/hello/")
    @app.route("/hello/<name>")
    def hello_there(name = None):
        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    
    
    
    @app.route("/api/data")
    def get_data():
        return app.send_static_file("data.json")
    
    if __name__ == '__main__':
        app.run(debug=True)

    hiflask/web.config

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <appSettings>
        <add key="WSGI_HANDLER" value="app.app"/>
        <add key="PYTHONPATH" value="D:homesitewwwroothiflask"/>
        <add key="WSGI_LOG" value="D:homesitewwwroothiflaskhiflasklogs.log"/>
      </appSettings>
      <system.webServer>
        <handlers>
        <add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:homepython364x64python.exe|D:homepython364x64wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/>
        </handlers>
      </system.webServer>
    </configuration>

    最终效果(作为子项目部署完成成功,所以一个app service就可以部署多个站点)

    提醒一点:App Service中如果要部署多站点,需要在Configration 中配置 Virtual Applications。

     参考资料:

    https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes/36033627#36033627

    https://www.cnblogs.com/lulight/p/15220297.html

    https://www.cnblogs.com/lulight/p/15227028.html

    当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/lulight/p/15251312.html
Copyright © 2011-2022 走看看