Url rewriting 使用Flask+;基于动态URL提供静态文件;Nginx?

Url rewriting 使用Flask+;基于动态URL提供静态文件;Nginx?,url-rewriting,nginx,rewrite,flask,Url Rewriting,Nginx,Rewrite,Flask,在Flask中,如果您将一个文件放在名为static/的目录中,那么任何http://localhost/static/foo.jpg将从static/foo.jpg提供该文件 这也可以通过nginx配置完成: location /static { alias /var/www/mywebsite/static; } 但是,我想做动态URL重写 如果有人请求URLhttp://localhost/username/foo.jpg,我想告诉nginx从任意U

在Flask中,如果您将一个文件放在名为
static/
的目录中,那么任何
http://localhost/static/foo.jpg
将从
static/foo.jpg
提供该文件

这也可以通过nginx配置完成:

    location /static {
        alias    /var/www/mywebsite/static;
    }
但是,我想做动态URL重写

如果有人请求URL
http://localhost/username/foo.jpg
,我想告诉nginx从任意URL获取静态文件,比如说,
/var/www/assets/11235/1bcd5.jpg
。我希望用户看到一个漂亮的url,并且希望位置对用户透明

有没有一个简单的方法可以做到这一点?理想情况下,我将能够做一些事情,以便nginx提供该文件。然而,如果Flask需要为它服务,那么也可以(我的项目还没有任何用户!)


这里我遗漏了什么?

如果文件可以用“漂亮”URL中直接引用的名称存储,那么您可以在nginx中进行简单的重写

但是,您似乎希望将URL路径信息映射到磁盘上的其他表示形式,如
username->11235
foo.jpg->1bcd5.jpg
。如果所提供的内容应该受到身份验证或会话的保护,那么您可能应该在Flask应用程序中保留映射和重写,因为Flask提供了实现这一点的方法

如果可以将内容视为公共内容,并且只需要完成映射,那么可以将nginx配置为获取查询字符串参数,在数据存储中查找它们,然后重写URL

以下是一个最初发布在nginx邮件列表上的邮件: 假设您的seo uri是/baz,真正的uri是/foo/bar。我有 我的本地mysql“测试”数据库中的下表:

create table my_url_map(id serial, url text, seo_url);
insert into my_url_map(url, seo_url)values('/foo/bar', '/baz');
我的nginx 0.8.41是这样构建的:

./configure \
--add-module=/path/to/ngx_devel_kit \
--add-module=/path/to/set-misc-nginx-module \
--add-module=/path/to/ngx_http_auth_request_module-0.2 \
--add-module=/path/to/echo-nginx-module \
--add-module=/path/to/lua-nginx-module \
--add-module=/path/to/drizzle-nginx-module \
--add-module=/path/to/rds-json-nginx-module
此外,我的系统中还安装了Lua5.1.4和LuaYajl库

这是我的nginx.conf的中心部分:

upstream backend {
    drizzle_server 127.0.0.1:3306 dbname=test
    password=some_pass user=monty protocol=mysql;
    drizzle_keepalive max=300 mode=single overflow=ignore;
}

lua_package_cpath '/path/to/your/lua/yajl/library/?.so';

server {
    ...

    location /conv-mysql {
        internal;
        set_quote_sql_str $seo_uri $query_string; # to prevent sql injection
        drizzle_query "select url from my_url_map where seo_url=$seo_uri";
        drizzle_pass backend;
        rds_json on;
    }

    location /conv-uid {
        internal;
        content_by_lua_file 'html/foo.lua';
    }

    location /jump {
        internal;
        rewrite ^ $query_string? redirect;
    }

    # your SEO uri
    location /baz {
        set $my_uri $uri;
        auth_request /conv-uid;

        echo_exec /jump $my_uri;
    }
}
基本胶水foo.lua的内容:

local yajl = require('yajl')
local seo_uri = ngx.var.my_uri
local res = ngx.location.capture('/conv-mysql?' .. seo_uri)
if (res.status ~= ngx.HTTP_OK) then
ngx.throw_error(res.status)
end
res = yajl.to_value(res.body)
if (not res or not res[1] or not res[1].url) then
ngx.throw_error(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
ngx.var.my_uri = res[1].url;
然后让我们从客户端访问/baz:

$ curl -i localhost:1984/baz
HTTP/1.1 302 Moved Temporarily
Server: nginx/0.8.41 (without pool)
Date: Tue, 24 Aug 2010 03:28:42 GMT
Content-Type: text/html
Content-Length: 176
Location: http://localhost:1984/foo/bar
Connection: keep-alive

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/0.8.41 (without pool)</center>
</body>
</html>
$curl-i localhost:1984/baz
HTTP/1.1 302临时移动
服务器:nginx/0.8.41(无池)
日期:2010年8月24日星期二03:28:42 GMT
内容类型:text/html
内容长度:176
地点:http://localhost:1984/foo/bar
连接:保持活力
302发现
302发现

nginx/0.8.41(无池)