我的博客的域名为allenwind.github.io,这是一个子域名。事实上,我们留意到很多web应用都有子域名,SaaS级别的应用更离不开子域名,企业为每个用户提供一个子域名。那么,如何实现这样的子域名呢?

实现

以Flask为例。假定有一个blog.com这样的域名,可以在上面创建博客,每个用户都有一个子域名,例如allenwind.blog.com

为了便于演示,视图函数只返回用户名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from flask import Flask, g

class Config:
SERVER_NAME = 'blog.com:8080'
DEBUG = True

def create_app():
app = Flask(__name__)
app.config.from_object(Config)
return app

app = create_app()

@app.url_value_preprocessor
def get_subdomain(endpoint, values):
g.subdomain = values.pop('subdomain')

@app.route('/', subdomain='<subdomain>')
def index():
user = g.site
# query user data from database
# and render user index page
return user

@app.route('/history/', subdomain='<subdomain>')
def history():
return g.subdomain + ' history'

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)

同时,需要在/etc/hosts(windows为C:\Windows\System32\drivers\etc)绑定域名,添加下面这一行:

127.0.0.1 allenwind.blog.com

以便本地域名查询找到该子域名对应的IP。

最后打开浏览器访问http://allenwind.blog.com:8080/即可看到输出allenwindhttp://allenwind.blog.com:8080/history/输出allenwind history

原理剖析

1
2
3
4
5
6
7
8
@setupmethod
def url_value_preprocessor(self, f):
"""Registers a function as URL value preprocessor for all view
functions of the application. It's called before the view functions
are called and can modify the url values provided.
"""
self.url_value_preprocessors.setdefault(None, []).append(f)
return f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def preprocess_request(self):
bp = _request_ctx_stack.top.request.blueprint
funcs = self.url_value_preprocessors.get(None, ())
if bp is not None and bp in self.url_value_preprocessors:
funcs = chain(funcs, self.url_value_preprocessors[bp])
for func in funcs:
func(request.endpoint, request.view_args)
funcs = self.before_request_funcs.get(None, ())
if bp is not None and bp in self.before_request_funcs:
funcs = chain(funcs, self.before_request_funcs[bp])
for func in funcs:
rv = func()
if rv is not None:
return rv-->

转载请包括本文地址:https://allenwind.github.io/blog/5108
更多文章请参考:https://allenwind.github.io/blog/archives/