V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
kingfighters
V2EX  ›  Python

前后端分离架构的上传文件问题

  •  
  •   kingfighters · 2018-11-23 09:42:00 +08:00 · 8091 次点击
    这是一个创建于 2197 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在撸一个前后端分离的网站,上传文件的时候思路卡住了,其实就是上传用户头像。

    其他的都解决,用户带 token,验证 token。但是头像这块该怎么搞?我看了网上的太多方案都不是可以用在这种前后端分离的。

    初步思路是这样:用户点击上传,把文件放在某个静态目录下,通过用户 id 生成一个文件名保存在数据库里面。但是这样会有两个问题:1.图片大小,格式校验在前端做还是后端做? 2,访问静态目录下的图片,使用后端生成的 url 还是后端直接读数据库,返回文件名,让前端生成 url ?还是 nginx 访问静态目录? 3. 用户只能一次只有一个头像,之前的全部丢失。。虽然这个不是什么大问题。

    求教各位大佬!

    24 条回复    2018-11-24 09:51:19 +08:00
    zjwshisb
        1
    zjwshisb  
       2018-11-23 09:49:44 +08:00
    上传成功后把图片的服务器路径和 url 返回给前端回显,前端表单提交的时候再存数据库
    1.校验前后端都要做吧
    2.肯定后端生成 url 呀,前端生成 url 的话如果后端域名变了不是要改
    liuzhedash
        2
    liuzhedash  
       2018-11-23 09:53:18 +08:00
    实在想不明白,就 base64 编码以后塞到数据库。
    这个所谓上传文件的问题,不是思路太少而是方法太多了,你愿意 base64 编码放数据库也行,愿意做个文件上传接口放到 web 目录下的静态内容文件夹也行,放到各大云服务商的静态存储也可以。
    你的 1,2,3 除了 1 必须在后端做验证之外,其他都没有一定的做法,要看你自己愿意做成啥样。
    Linxing
        3
    Linxing  
       2018-11-23 10:06:04 +08:00
    我们前后端分离 前端去请求文件服务器的接口 像一楼说的 把返回的 URL 放 json 提交给后端就好了
    sytnishizuiai
        4
    sytnishizuiai  
       2018-11-23 10:32:14 +08:00
    就像 2 楼说的,base64 很方便,而且头像这种不需要精度很高的图片,又简单又快。
    zrrd
        5
    zrrd  
       2018-11-23 10:33:02 +08:00
    先上把上传文件标记为临时文件,当要保存这条数据的时候再把这个文件保存为永久文件,定期清理临时文件
    whypool
        6
    whypool  
       2018-11-23 10:55:38 +08:00
    文件存储一般是单独的文件 server,可以用云或者自己建一个

    上传一般要带 token 签名,由应用生成签名,下发给前端,前端执行 upload,文件 server 校验签名

    文件 server 应该有临时目录和永久目录

    前端成功上传,返回文件 uuid,提交叫数据库保存的时候,应用要 call 一次文件 server 接口,文件永久保存

    文件校验在前端,文件 server 不做任何格式,大小校验,只验证签名

    虽然比较复杂,但是推荐这样做,方便平行扩容,备份,容灾

    简单省事就放应用静态目录
    loveCoding
        7
    loveCoding  
       2018-11-23 11:01:03 +08:00
    后端提供统一的文件上传接口,返回 url 给前端 ,前端再提交后端啊.
    vitoaaazzz
        8
    vitoaaazzz  
       2018-11-23 11:16:54 +08:00   ❤️ 1
    说下我们现在的文件处理方式:
    1. 有一个统一的文件存储服务供所有业务使用,所有业务的文件存储都依赖该文件服务进行保存。文件服务的具体存储依赖 oss。

    2. 统一文件上传处理逻辑
    1. 前端文件上传到统一的文件上传接口
    2. 文件上传接口接收上传的文件,记录文件缓存,同时给前端返回文件 id、文件 url
    3. 前端调用业务接口时带上文件 id,如保存头像接口
    4. 业务接口会通过文件 id 调用文件存储服务做持久化存储,并将文件 id 记录到 user 表中
    5. 前端请求用户头像的时候后端将记录的头像文件 id 生成 url 返回给前端。
    lolizeppelin
        9
    lolizeppelin  
       2018-11-23 11:30:24 +08:00
    如果只是简单的后台上传不提供给用户

    给客户端分配 token, 并提供上传 ip 端口
    服务点用这个 token 信息启动一个 websocket 进程 传完关闭进程
    acr0ss
        10
    acr0ss  
       2018-11-23 11:33:09 +08:00
    找个云存储,有前端的 SDK,使用 SDK 直接传云存储,返回 url,然后保存表单的时候访问服务器。
    Mrkon
        11
    Mrkon  
       2018-11-23 11:52:20 +08:00
    业务量小的话,可以使用七牛云的免费图片存储(后端调用接口)。然后数据库保存 url,将 url 返回给前端。对于图片限制,需要前后端都做,不过七牛云可以制定图片,解决了你后端再限制的麻烦。
    FrankFang128
        12
    FrankFang128  
       2018-11-23 11:55:00 +08:00
    用 base64 怎么做 CDN 和缓存? 总不能缓存 user json 缓存十年吧
    luozic
        13
    luozic  
       2018-11-23 12:28:11 +08:00
    數據庫存鏈接地址,這種實際直接可以用 lua+niginx 寫個插件 直接存 redis 啥的搞定。
    reus
        14
    reus  
       2018-11-23 12:50:25 +08:00   ❤️ 3
    这和前后端分离有啥关系?
    maichael
        15
    maichael  
       2018-11-23 12:55:18 +08:00
    用户上传文件,后端放到静态文件里( CDN 也可以),然后把 url 写数据库。
    1. 前后都要做校验。
    2. 多个头像这个看具体需求,反正就是一个保存多个 URL 的事。
    Malthael
        16
    Malthael  
       2018-11-23 13:28:38 +08:00
    前端校验上传图片,后端将图片放到 oss 上,将路径存到数据库,前端显示的时候后端生成 url 传给前端。
    你也可以将文件放到你的项目目录下。
    k9982874
        17
    k9982874  
       2018-11-23 13:35:43 +08:00   ❤️ 1
    我觉得你对前后端分离有误解
    initsa
        18
    initsa  
       2018-11-23 14:13:14 +08:00
    base64 ? 图片大的话 确定那么多字符能存到表里? 应该前端用 FormData 上传 , 后端获取解析 存对象存储里面, 把路径名称存数据库才对吧···
    gzf6
        19
    gzf6  
       2018-11-23 14:22:18 +08:00
    base64
    aspromiss
        20
    aspromiss  
       2018-11-23 15:24:53 +08:00   ❤️ 1
    为什么上面说的都没有看出来什么呢.....
    我想楼主可能是因为公司的项目是纯前后端分离,且 Node 本身负责了前端的渲染,造成了上传文件的时候,可以直接在前台上传到服务器上,也可以通过 Node 使用 pipe 流到后台,由后台的接口上传文件。
    这个地方因为前后端完全分离,也困扰了我们很久,最后我们认为由 Node pipe 流到后台,虽然这样符合 Node 前台服务器作为转发中间层的定义,但是后台再次上传实在是太浪费资源。上传文件最终完全由前台来做了,只是上传完成后后的文件名和路径等信息由前台转发给后台,让后台存储这些上传后的资源信息
    fumichael
        21
    fumichael  
       2018-11-23 15:35:51 +08:00
    base64 放数据库,are you ok ???

    url 不就是一个特别一点的字符串,跟 user 的 name 字段有区别吗?

    图片上传,保存图片的 url 就可以啦
    本地可以存相对地址,云储存需要多一个域名(/user/avatar/1.jpg ) vs ( http://domain.com/image/1.jpg)

    图片上传,上传到本地,上传到七牛等云存储都可以

    数据校验最好是前后段都要做啦,前端文件改个后缀不就能绕过了嘛(前端校验为了体验,后端校验为了安全)
    514656282
        22
    514656282  
       2018-11-23 16:55:36 +08:00
    实在不懂这个跟前后端分离有什么关系
    behanga
        23
    behanga  
       2018-11-23 17:12:26 +08:00
    用户头像什么的不都是该放在 CDN 上吗? 这些一般都是上传到 CDN 上,然后 callback 回来后,在 call 后端的 api,后端 api 一般就存个 url
    Outliver0
        24
    Outliver0  
       2018-11-24 09:51:19 +08:00
    docker 一个 fastdfs 系统,在 storage 上搭个 nginx 提共静态文件服务,可以试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 12:19 · PVG 20:19 · LAX 04:19 · JFK 07:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.