Flask 与 VUE 前后端跨域问题

文章介绍了在使用Flask和Vue进行前后端分离开发时遇到的跨域问题,解释了跨域的原理和同源策略。通过W3C的CORS规范,文章详细讲解了如何在Flask中配置CORS,包括使用@cross_origin装饰器和CORS函数两种方法,以及注意事项,特别提到了支持带凭证的请求配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做一个小型的web项目,使用了 Flask 与 VUE 做前后端分离,被跨域问题所困扰,经过一番学习,发现了一篇大佬写的博客,担心以后找不到了,特此转载以做记录。

转载自:Flask配置Cors跨域

1、对跨域问题的理解

在这里插入图片描述
跨域是指:浏览器A服务器B 加载页面,在页面的 JS 中使用 Ajax 访问 服务器C 的接口。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。

同源策略是指:浏览器A服务器B 获取的静态资源,包括Html、Css、Js,为了用户安全,浏览器加了限制,其中的Js通过Ajax只能访问 服务器B 的静态资源或请求。即:浏览器A从哪个服务器获取的资源,那资源中的请求就只能访问相同的服务器

同源是指:同一个请求协议(如:Http或Https)、同一个Ip、同一个端口,3个全部相同,即为同源。

2、跨域的处理

跨域的这种需求还是有的,因此,W3C组织制定了一个Cross-Origin Resource Sharing规范,简写为Cors,现在这个规范已经被大多数浏览器支持,从而,处理跨域的需求。

Cors需要在后端应用进行配置,因此,是一种跨域的后端处理方式,这么做也容易理解,一个你不认识的源来访问你的应用,自然需要应用进行授权。除了后端处理方式,也有前端的解决方案,如:JSONP,因这里我们主要讲解Flask对Cors的配置,暂不对前端解决方案进行详细说明。

3、跨域的分类

跨域分为以下3种

名称英文名说明
简单请求Simple Request发起的Http请求符合:
1.无自定义请求头。
2.请求动词为GET、PUT或POST之一。
3.动词为POST时,Content-Type是application/x-www-form-urlencoded multipart/form-data或text/plain之一
预检请求Preflighted Request发起的Http请求符合其中之一:
1.包含了自定义请求头。
2.请求动词不是GET、PUT或POST。
3.动词是POST时,Content-Type不是application/x-www-form-urlencoded multipart/form-data或text/plain。 即:简单请求的相反 。
凭证请求Requests with Credential发起的Http请求中带有凭证

4、Flask 配置 Cors

Flask配Cors跨域,使用Flask-CORS包,详细文档,参见: https://flask-cors.readthedocs.io/en/latest/,总的来说,flask-cors包也提供了两种方式。

方式范围说明
@cross_origin装饰器配置单个路由适用于配置特定的API接口
CORS函数配置全局API接口适用于全局的API接口配置

4.1 安装 flask-cors

pip install flask-cors

4.2 跨域处理

4.2.1 方法一:使用@cross_origin装饰器

@app.route("/")
@cross_origin()
def helloWorld():
  return "Hello, cross-origin-world!"

>>装饰器参数说明

装饰器参数类型Head字段说明
origins列表、字符串或正则表达式Access-Control-Allow-Origin配置允许跨域访问的源,*表示全部允许
methods列表、字符串Access-Control-Allow-Methods配置跨域支持的请求方式,如:GET、POST
expose_headers列表、字符串Access-Control-Expose-Headers自定义请求响应的Head信息
allow_headers列表、字符串或正则表达式Access-Control-Request-Headers配置允许跨域的请求头
supports_credentials布尔值Access-Control-Allow-Credentials是否允许请求发送cookie,false是不允许
max_age整数、字符串Access-Control-Max-Age预检请求的有效时长

4.2.2 方法二:使用CORS函数

>>全局应用

app = Flask(__name__)
cors = CORS(app, resources={r"/test/*": {"origins": "*"}})

@app.route("/test/index")
def index():
  return "hello flask"

>>单独蓝图配置

test_bp = Blueprint('test', __name__)
CORS(test_bp, resources={r"/test/*": {"origins": "*"}}) 

@test_bp.route("/test/index")
def index():
  return "hello flask"

>>CORS函数参数说明

参数类型Head字段说明
resources字典、迭代器或字符串全局配置允许跨域的API接口
origins列表、字符串或正则表达式Access-Control-Allow-Origin配置允许跨域访问的源,*表示全部允许
methods列表、字符串Access-Control-Allow-Methods配置跨域支持的请求方式,如:GET、POST
expose_headers列表、字符串Access-Control-Expose-Headers自定义请求响应的Head信息
allow_headers列表、字符串或正则表达式Access-Control-Request-Headers配置允许跨域的请求头
supports_credentials布尔值Access-Control-Allow-Credentials是否允许请求发送cookie,false是不允许
max_age整数、字符串Access-Control-Max-Age预检请求的有效时长

5、注意事项(后面碰到其他问题会继续补充)

  1. 对于需要返回 cookie 的请求,需要设置 supports_credentials=true
    例:
    在这里插入图片描述
    就是因为前端请求位于云端服务器的登录服务,云端服务器需要返回用于保持登陆状态的session,所以应该在跨域处理时手动将 supports_credentials 设置为 true
    后台代码如下:
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)

# 跨域处理 resources=r'/*' 表示针对所有路由有效
CORS(app, resources=r'/*', supports_credentials=True)

@app.route('/')
def index():
	retrun "hello flask"

@app.route('/login', methods=['POST'])
def login():
	'''
	登陆代码
	'''
	return "login success"

if __name__ == '__main__':
    app.run()
<think>嗯,用户想要生成一份包含前后端功能实现的文档,涉及上传模块、VUE页面嵌入和HTML播放嵌入的功能需求。我需要仔细分析他们的需求,然后结合提供的引用内容来给出合适的解决方案。 首先,上传模块部分,用户可能需要前后端的协作。后端需要处理文件上传,可能需要用到Spring Boot,因为引用[1]提到RuoYi是基于Spring Boot的,所以可以参考其架构。文件存储方面,本地存储和云存储都是常见方案,可能需要分块上传和进度条功能,这部分可以结合引用[2]提到的API文档生成,确保接口清晰。 然后是VUE页面嵌入,用户可能希望在现有的Vue项目中集成上传组件和视频播放。引用[3]和[4]提到了海康威视的视频播放解决方案,尤其是使用HLS协议,可能需要用到video.js或者海康的插件。同时,上传组件需要后端API对接,可能需要使用Axios进行文件上传,并处理进度和结果反馈。 HTML播放嵌入部分,用户可能需要在不使用Vue的情况下嵌入播放器,比如传统的HTML页面。这时候可能需要直接使用海康的Web插件或者EasyPlayer,如引用[3]和[4]所提到的,需要处理不同协议的视频流,比如RTMP或HLS,并确保浏览器兼容性。 另外,用户提到的生成完整文档,需要结构清晰,分模块说明前后端实现步骤,可能还需要代码示例和注意事项。引用[2]中提到的Swagger集成可以用于API文档,方便前后端协作。同时,引用[1]中的一键生成功能可能对快速开发有帮助,但用户可能需要手动编写文档。 需要确保各模块之间的集成,比如上传后的文件如何被播放组件访问,可能需要返回文件的URL或存储路径。安全方面,引用[1]提到XSS防范,上传模块需做文件类型校验和病毒扫描。视频播放要考虑协议支持和延迟问题,引用[3]提到HLS协议可能更合适,因为RTMP依赖Flash已经过时。 测试部分,可能需要本地调试和部署后的不同配置,如引用[4]提到的部署后连接问题,需确保和HTTPS处理。可能还需要考虑分块上传和大文件处理,引用[3]中的nginx流媒体服务器可能相关,但用户提到海康可能不支持推流,所以可能需要直接拉流。 总结下来,需要分模块详细说明前后端实现,提供代码示例,并注意安全、兼容性和性能优化。同时,引用相关技术点,如Spring Boot、Vue组件、海康插件等,确保方案可行。</think># 前后端功能集成实现文档 ## 一、文件上传模块开发 ### 1. 后端实现(Spring Boot) ```java // 文件上传接口 @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) { String fileName = FileUtils.upload(file); // 文件存储逻辑 return ResponseEntity.ok("上传成功:" + fileName); } // 文件分块上传接口 @PostMapping("/chunk-upload") public ResponseEntity<String> chunkUpload(@RequestParam("chunk") MultipartFile chunk, @RequestParam("chunkNumber") int chunkNumber, @RequestParam("totalChunks") int totalChunks) { FileUtils.mergeChunks(chunk, chunkNumber, totalChunks); return ResponseEntity.ok("分块上传成功"); } ``` *技术特性:* - 支持单文件/分块上传 - 集成Swagger API文档[^2] - 多存储方案适配(本地/OSS) ### 2. 前端实现(Vue3) ```vue <template> <input type="file" @change="handleUpload"> <progress :value="progress" max="100"></progress> </template> <script setup> const handleUpload = async (e) => { const file = e.target.files[0]; const formData = new FormData(); formData.append('file', file); const res = await axios.post('/api/upload', formData, { onUploadProgress: progressEvent => { progress.value = Math.round((progressEvent.loaded * 100) / progressEvent.total); } }); } </script> ``` ## 二、视频播放模块集成 ### 1. VUE页面嵌入方案 ```vue <template> <div ref="videoContainer"></div> </template> <script setup> import { onMounted } from 'vue'; import '@easydarwin/easyplayer/dist/easyplayer.min.css'; import '@easydarwin/easyplayer/dist/easyplayer.min.js'; onMounted(() => { new EasyPlayer({ container: videoContainer.value, videoUrl: 'https://example.com/live.m3u8', protocol: 'hls' // 海康HLS协议支持[^3] }); }); </script> ``` ### 2. HTML直接嵌入方案 ```html <div id="hikplayer" style="width:800px;height:600px"></div> <script src="https://open.hikvision.com/plugins/webVideoCtrl.js"></script> <script> WebVideoCtrl.I_InitPlugin(800, 600, { szProtocol: 'hls', cbSelDevice: function() { WebVideoCtrl.I_StartPreview('hikplayer', '192.168.1.64'); } }); </script> ``` ## 三、系统集成要点 1. **接口安全设计** - 上传接口需增加文件类型白名单校验 - 视频播放接口启用Token鉴权 - 集成Shiro权限控制[^1] 2. **部署配置要求** ```yaml # application.yml hikvision: api: preview-url: /api/video/v2/cameras/previewURLs protocol: hls storage: max-file-size: 2GB chunk-size: 10MB ``` 3. **性能优化建议** - 使用Nginx代理视频流分发[^3] - 启用CDN加速上传下载 - 视频分片加载实现秒开 ## 四、测试验证流程 1. 本地开发环境 ```bash # 启动后端服务 mvn spring-boot:run # 前端调试 npm run dev -- --port 8081 ``` 2. 生产环境部署 ```nginx # Nginx配置示例 location /live { proxy_pass http://media_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } ``` ## 五、常见问题解决方案 | 问题现象 | 排查方向 | 解决方案 | |---------|---------|---------| | 视频黑屏 | 协议兼容性 | 强制使用HLS协议[^4] | | 上传中断 | 网络波动 | 启用分块续传机制 | | 问题 | 安全配置 | 添加CORS响应头[^1] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值