如果文件可以使用“漂亮” URL 中直接引用的名称存储,那么您可以在 nginx 中进行简单的重写。
但是,您似乎希望将 URL 路径信息映射到磁盘上的其他表示形式,如username -> 11235
和foo.jpg -> 1bcd5.jpg
. 如果所提供的内容应该受到身份验证或会话的保护,那么您可能应该将映射和重写保留在您的 Flask 应用程序中,因为 Flask 提供了这样做的方法。
如果内容可以被视为公共内容并且只需要完成映射,则可以将 nginx 配置为获取查询字符串参数,在数据存储中查找它们,并重写 URL。
考虑你的 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
另外,我的系统中安装了 lua 5.1.4 和 lua-yajl 库。
这是我的 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>