Bra*_*len 5 https nginx fastapi uvicorn
我有一个小型的测试 FastAPI Web 应用程序,它提供一个简单的 HTML 页面,该页面需要位于静态文件夹中的 css 样式表。它安装在 Linode 服务器(Ubuntu 20.04 LTS)、nginx、gunicorn、uvicorn 工作人员和supervisorctl 上。我已经使用 certbot 添加了证书。
该应用程序在 http 中工作正常,但无法访问 https 中的静态文件。当通过 http 访问时,所有基于静态的功能都可以工作,但是当通过 https 访问时,它缺少 css 样式表中的所有样式。我需要让它工作,这样我就可以加载一个需要 css 和其他静态文件夹存储功能的更复杂的应用程序。
文件结构为:
/home/<user_name>/application
- main.py
- static
|_ css
|_ bootstrap
- templates
|_ index.html
Run Code Online (Sandbox Code Playgroud)
主要.py:
import fastapi
import uvicorn
from fastapi import Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
api = fastapi.FastAPI()
api.mount('/static', StaticFiles(directory='static'), name='static')
templates = Jinja2Templates(directory="templates")
@api.get('/')
@api.get('/index', response_class=HTMLResponse)
def index(request: Request):
message = None
return templates.TemplateResponse("index.html", {"request": request,
'message': message})
if __name__ == '__main__':
uvicorn.run(api, port=8000, host='127.0.0.1')
Run Code Online (Sandbox Code Playgroud)
nginx 位于 /etc/nginx/sites-enabled/<my_url>.nginx
server {
listen 80;
server_name www.<my_url>.com <my_url>.com;
server_tokens off;
charset utf-8;
location / {
try_files $uri @yourapplication;
}
location /static {
gzip on;
gzip_buffers 8 256k;
alias /home/<user_name>/application/static;
expires 365d;
}
location @yourapplication {
gzip on;
gzip_buffers 8 256k;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
server {
listen 443 ssl;
server_name www.<my_url>.com;
ssl_certificate /etc/letsencrypt/live/<my_url>.com/fullchain.pem; # mana>
ssl_certificate_key /etc/letsencrypt/live/<my_url>.com/privkey.pem; # ma>
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
try_files $uri @yourapplication;
}
location /static {
gzip on;
gzip_buffers 8 256k;
alias /home/<user_name>/application/static;
expires 365d;
}
location @yourapplication {
gzip on;
gzip_buffers 8 256k;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用主管脚本提供服务:
[program:api]
directory=/home/<user_name>/application
command=gunicorn -b 127.0.0.1:8000 -w 4 -k uvicorn.workers.UvicornWorker main:api
environmentenvironment=PYTHONPATH=1
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/app/app.err.log
stdout_logfile=/var/log/app/app.out.log
Run Code Online (Sandbox Code Playgroud)
css 样式表在 html 中使用 url_for 调用,如下所示:
<link href="{{ url_for('static', path='/css/ATB_style.css') }}" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)
我尝试了对 nginx 中的 location /static 块进行大量修改,包括:
我已经加载了这个服务器两次,一次让 certbot 修改 nginx 文件,第二次是当前配置,我手动完成的。我完全不知道该怎么办。
感谢@AdramKhan 的评论,为重要的演示提供了解决方法。我在 html 页面中添加了一条元行,以允许使用 https 访问 css 样式表:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
Run Code Online (Sandbox Code Playgroud)
这只是一个解决方法,因为它正在处理代码中某处的硬编码 HTTP 请求: How can I allowed Mixed content (http with https) using content-security-policy meta tag?
解决根本原因是改变 html 文件头中静态内容的调用方式。问题(共有三个)是这样的引用,其中有 jinja2 url_for 而不是直接 href:
<link href="{{ url_for('static', path='/css/MH_style.css') }}" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)
当替换为这种格式的引用时,使用 href:
<link rel="stylesheet" href="/static/css/MH_style.css"/>
Run Code Online (Sandbox Code Playgroud)
没有内容安全策略元,一切都可以正常工作。
| 归档时间: |
|
| 查看次数: |
4291 次 |
| 最近记录: |