SERVER_NAME in Flask mainly does two things:
- Assist Flask in generating absolute URLs outside of active requests (such as embed website URLs in emails)
- For subdomain support
Many people mistakenly think that it can do other things besides these two things.
1. First thing: Absolute URL
We know that url_for generates a relative URL by default, and it has a parameter _external. If set to true, an absolute URL will be generated (that is, HTTP starts with domain names and other information). If SERVER_NAME is not specified, the currently active request is used by default to generate the URL.
Here is an example to demonstrate:
# filename from flask import Flask, url_for app = Flask(__name__) @('/') def index(): return 'hello flask' @('/test') def test(): return url_for('index', _external=True) if __name__ == '__main__': (debug=True)
1.【Scenario 1】Access through the browser
After the app is run, listen on the local port 5000.
(env) F:\tmp>python * Running on http://127.0.0.1:5000/ * Restarting with reloader
If we access http://127.0.0.1:5000/test through the browser, the returned content is: http://127.0.0.1:5000/.
If we access http://localhost:5000/test through the browser, the returned content is: http://localhost:5000/.
It can be seen that without setting SERVER_NAME, the absolute URL generated by url_for is dependent on the requested URL. Let’s take a look at the situation where it is not accessible through the browser.
2. [Scenario 2] Non-browser access
This scenario refers to the situation where there is no request request.
We simulate it through Python Shell:
>>> from myapp import app >>> with app.app_context(): ... print url_for('index', _external=True) ...
Traceback (most recent call last): File "<stdin>", line 2, in <module> File "F:\tmp\env\lib\site-packages\flask\", line 287, in url_for raise RuntimeError('Application was not able to create a URL ' RuntimeError: Application was not able to create a URL adapter for request indep endent URL generation. You might be able to fix this by setting the SERVER_NAME config variable.
The above means that the application cannot create a URL adapter for URL generation that is not related to request, and this problem can be solved by setting SERVER_NAME.
OK, let's try it after setting a value for SERVER_NAME:
>>> ['SERVER_NAME'] = '' >>> with app.app_context(): ... print url_for('index', _external=True) ...
/
PS: Generally SERVER_NAME is set as the domain name of the website.
There is a passage in the Flask-Mail-related article:
Many Flask extensions assume that they run in an active application and request context. Flask-Mail's send function uses the current_app context. Therefore, when the() function is executed in a thread, a context needs to be created manually. All the app.app_context() is used in send_async_email to create a context.
Therefore, to generate an absolute URL that does not depend on request (such as the URL of a website page generated in the email when sending emails asynchronously), you must set SERVER_NAME.
Second thing: Subdomain name support
The SERVER_NAME key is used for subdomain support. Because Flask cannot guess the subdomain part before knowing the existing server name, this option is necessary and is also used for session cookies if you want to use the subdomain.
Please remember that Flask is not the only problem of not knowing the subdomain name, but your browser also has this problem. Most modern web browsers do not allow cross-subdomain cookies with server names that do not contain dots. So if your server's name is localhost, you will not be able to set a cookie for localhost and all its subdomains. Please select a suitable server name, like '', and add the server name you want + subdomain to your host configuration or set a local bind.
Examples
--------> || --------> || -------->
1. Local testing
Modify the /etc/hosts file
Note: Only valid in local testing!
Add all subdomains to it, for example:
127.0.0.1 localhost # Domain Name127.0.0.1 localhost # Subdomain name127.0.0.1 localhost # Subdomain name
Add 'SERVER_NAME' to the Flask app's configuration file
Set 'SERVER_NAME' to the specified domain name and the default listening port in the application configuration, for example:
#... app = Flask(__name__) ['SERVER_NAME'] = ':5000' #...
2. Configure blueprint
The subdomain in the blueprint is the subdomain added in the hosts file
#... # Blueprint declaration bp = Blueprint('subdomain', __name__, subdomain="<user>") #... # Register the blueprint into the application app.register_blueprint(bp) #...
3. Server-side configuration
Tell us that the 'SERVER_NAME' in the Flask application settings is modified to the domain name registered in the production environment
:5000 ---->
Configuration
Configure the listening port. In the following example, use a regular expression to obtain the subdomain name that the user accesses. For www, it should be filtered when the regular expression is obtained and redirected to the page when the user accesses, otherwise www will be regarded as a subdomain name.
Configuration instance:
server { listen 80; listen 443 ssl; ssl_certificate /usr/local/nginx/ssl/; ssl_certificate_key /usr/local/nginx/ssl/; server_name ~^www\.(?<user>.+\.)?markdownblog\.com$; return 301 "$scheme://${user}$request_uri"; } server { listen 80; listen 443 ssl; ssl_certificate /usr/local/nginx/ssl/; ssl_certificate_key /usr/local/nginx/ssl/; server_name ~^.+\.markdownblog\.com$ ; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8085; } }