| 前端 | 后端 | |
|---|---|---|
| 技术栈 | Vue + Element UI | Flask |
| 部署方式 | 静态文件打包dist上传CDN | 使用uwsgi部署在一台服务器上,在内网内使用IP:port访问 |
1. 上传后渲染有问题,全部为文本样式
页面表现如下图
原因为请求CDN的css文件的响应头中content-type错误,被指定成了text/plain,应指定为正确的css格式如下图
在上传CDN时需要对文件类型指定正确,且CDN保证响应文件请求时在响应头中携带正确的content-type,同理html也应注意文件类型
files = [
('file', ('xxx.css', open('{path_to_css_file}', 'rb'), 'text/css'))
]
2. axios访问后端API
由于后端服务部署在其他地方(http://10.111.152.165:10000/),CDN(https://cdn.xxx.com)需要访问非本地资源,如果不做处理,axios请求接口时使用的host仍为CDN域名,则会404。需要在axios公共配置中配置baseURL,找到引入axios的axios.js文件,增加如下配置:
// axios.js
const config = {
baseURL: process.env.baseURL || "http://10.111.152.165:10000/",
timeout: 60 * 1000, // Timeout
};
3. CDN域名下请求后端API带来跨域问题
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。跨域问题出于浏览器的同源策略限制。浏览器错误如下两图
跨域请求又可以分为简单请求和非简单请求,简单请求不会发送OPTIONS预检请求,非简单请求会首先发送OPTIONS预检请求,详细过程请移步CORS详解
解决方案:
- 前端:添加跨域请求头Origin,可在axios.js全局axios配置处进行配置
// axios.js axios.defaults.headers.common['Origin'] ='https://cdn.xxx.com'; //CDN域名
- 后端:配合前端添加跨域响应头,即给响应头添加以下三个header
Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, PUT, POST, DELETe, HEAD, OPTIONS Access-Control-Allow-Origin: https://cdn.xxx.com
可以做成全局方式,安装flask-cors插件,在create_app时配置
# __init__.py
from flask import Flask
from flask_cors import *
def create_app(config_name):
app = Flask(__name__)
# 读取项目配置信息
app.config.from_object(config)
# 允许跨域请求
CORS(app, supports_credentials=True)
...
本地调试或临时处理跨域问题时,可给Chrome安装Allow CORS: Access-Control-Allow-Origin插件,它相当于一个代理,可以给浏览器收到的响应添加跨域头部
4. HTTPS资源混合HTTP请求
Chrome浏览器不允许在https协议的页面里请求http的资源,由于后端使用的是HTTP协议,而前端CDN使用HTTPS协议,带来Chrome浏览器HTTPS站点内访问HTTP资源的报错(block:mixed-content),如下两图
解决方案:
- 前端:前端index.html文件中添加如下代码,可将HTTP请求转换为HTTPS请求
- 后端:需要同步修改为HTTPS协议,引入SSL,申请公司可用的证书,或使用OpenSSL自己生成自签证书(自签证书需要每次操作浏览器信任,不是最终的办法),运行方式加上ssl_context,Flask启动方式如下:
# manager.py
app.run(host='0.0.0.0',port=5000,ssl_context=('./server.crt','./server.key'))
未完待续



