V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
这是一个专门讨论 idea 的地方。

每个人的时间,资源是有限的,有的时候你或许能够想到很多 idea,但是由于现实的限制,却并不是所有的 idea 都能够成为现实。

那这个时候,不妨可以把那些 idea 分享出来,启发别人。
XiaoXiaoNiWa
V2EX  ›  奇思妙想

一个上传图片的新思路

  •  
  •   XiaoXiaoNiWa · 2015-12-30 12:21:07 +08:00 · 5149 次点击
    这是一个创建于 3255 天前的主题,其中的信息可能已经有所发展或是发生改变。
    咱自己的博客用的贴图库免费图床,感觉速度还挺快,但是对国内线路不友好,并在部分运营商位置被墻。所以 Pangnet 套上一层百度云加速,虽然页面加载很快,但图片加载还是很感人,页面访问时一片白,主要时间都浪费在载图上。
    既然图片可以转成 base64 ,为什么没有看到国内站点用此方法存图进数据库而非本地磁盘,来实现廉价的加速呢?(在 cdn 速度不赖的情况下)
    37 条回复    2016-01-03 13:19:13 +08:00
    Andy1999
        1
    Andy1999  
       2015-12-30 12:22:38 +08:00 via iPhone
    如果全部写成 base64 页面需要等加载全部完成才行
    这样子就是页面都打开巨慢了
    XiaoXiaoNiWa
        2
    XiaoXiaoNiWa  
    OP
       2015-12-30 12:24:54 +08:00
    @Andy1999 但是现在图不加载完,页面也不显示啊…
    bk201
        3
    bk201  
       2015-12-30 12:27:15 +08:00
    没看懂为何存在数据库里就加速了。
    Andy1999
        4
    Andy1999  
       2015-12-30 12:32:28 +08:00 via iPhone
    @XiaoXiaoNiWa 这个应该框架先加载 再加载其他资源
    XiaoXiaoNiWa
        5
    XiaoXiaoNiWa  
    OP
       2015-12-30 12:40:40 +08:00
    @Andy1999 线上说:)
    Felldeadbird
        6
    Felldeadbird  
       2015-12-30 12:43:29 +08:00
    你将图片放进数据库,如何 异地 CDN 呢?。每次部署服务器都要 安装一次 数据库?不妥不不妥
    kaneg
        7
    kaneg  
       2015-12-30 12:48:41 +08:00
    对于一些比较小的图片,比如 logo ,图标等是节省请求次数的好办法,但对于大图片的就不太适用了,再加上一个 html 文件中引用很多图片,会造成 html 文件大小剧增。除此外浏览器也无法对图片进行缓存,无法利用 CDN 加速等问题
    XiaoXiaoNiWa
        8
    XiaoXiaoNiWa  
    OP
       2015-12-30 13:00:43 +08:00
    @kaneg @Felldeadbird 那只能单独加载图?还是单独弄个静态文件域?
    dacapoday
        9
    dacapoday  
       2015-12-30 13:17:44 +08:00
    base64 的话,体积不是更大了吗
    oott123
        10
    oott123  
       2015-12-30 13:18:04 +08:00
    数据库不还是在文件系统里?也还是要钱啊。
    irainsoft
        11
    irainsoft  
       2015-12-30 13:32:58 +08:00
    然后别人右键看你 HTML 时满眼都是 base64 编码 hhhh
    msg7086
        12
    msg7086  
       2015-12-30 13:53:12 +08:00
    你传送的数据不仅没有减少,反而变多了……

    能快起来才怪。
    libook
        13
    libook  
       2015-12-30 14:31:42 +08:00   ❤️ 1
    有木有做过实验?同一张图片本身的大小与其转换成 Base64 的字符串大小的对比?
    推荐的方案是 CDN 镜像:

    如果你的图片在自己的服务器上的话。

    1. 用户访问你的服务器反向代理服务器
    2. 反向代理服务器发现这是一个静态资源(比如 http://myblog.host/abc.png ),返回一个 307+CDN 资源地址( http://cdn.host/abc.png ),如果你的文件内容几乎不会加修改的话可以让反向代理服务器给这种需要 307 的请求加浏览器端缓存,这样一段时间内浏览器下次需要这个文件就不会去你的服务器请求,直接去访问 307 指定的地址
    3. 浏览器会去向 CDN 重新请求这个静态资源
    4. CDN 接收到请求,看自己节点上是否有这个文件,有就直接返回文件,没有就继续
    5. CDN 上之前配置好了网站的另一个域名( http://forcdn.myblog.host ),所以 CDN 会直接去这个域名拿文件( http://forcdn.myblog.host/abc.png ),其实和之前的那个域名是同一个站点,只是由于域名不同,所以反向代理服务器的策略不同,这个域名会直接返回文件( abc.png )给 CDN , CDN 将文件存在自己的服务器上,以备提供给以后相同的请求
    6. CDN 将文件返回给用户, CDN 上也可以配置浏览器端缓存,这样的话浏览器下次需要显示同一张图片就不需要去服务器请求,直接读本地缓存
    7. 文件在用户的浏览器上显示

    如果你的图片不在自己的服务器上的话可以将那个自己网站的 CDN 专用域名( http://forcdn.myblog.host )改成图床的地址,就可以实现加速图床的效果。

    现在好多 CDN 都有这种镜像功能,你可以挑一个网络比较好的,而且对个人用途免费额度高的。

    如果没看懂的话可以再问我,我公司的服务所有静态资源都是这种形式,服务器绝大多时间都只需要处理 API 请求,静态文件请求的处理和流量都在 CDN 上面。
    alian
        14
    alian  
       2015-12-30 15:56:24 +08:00
    @libook 看了下解决方案是使用 CDN 镜像:图片在自己服务器上,通过反向代理去 cnd 取图片,如果图片存在则反回图片,不存在则重新会自己服务器拉取图片(使用的域名不同)。反向代理和 CDN 都可以配置浏览器缓存。 是这样意思对么?顺便问下为什么不是 302 而是 307 呢?查了下 307 :对于 POST 请求,表示请求还没有被处理,客户端应该向 Location 里的 URI 重新发起 POST 请求。
    break
        15
    break  
       2015-12-30 16:11:14 +08:00 via iPhone
    其实严格意义 base64 图片都算不上优化方案, base64 后减少一个请求但增大了页面体积,舍本逐末的感觉,多图片的页面,可以考虑多域名保存图片的方式,这样图片是多个并发加载的,请求数不会减慢页面加载速度,小图标减少请求数的优化方案应该是 spirite 或者 webfont ,然后是图片的无损压缩,图片按需使用不同尺寸缩略图都可以提高加载速度加载速度
    XiaoXiaoNiWa
        16
    XiaoXiaoNiWa  
    OP
       2015-12-30 16:17:53 +08:00
    @libook 想了解详细,您的联系方式是?
    libook
        17
    libook  
       2015-12-30 16:23:44 +08:00
    @alian 思路对了,就是不知道你从哪里了解的 307,了解这些东西当然还是要去权威的地方嘛 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 大概就是 307 代表暂时的重定向。使用状态码要看浏览器对不同状态吗的处理,有兴趣你自己可以研究一下。

    我写的这种是针对于图片在自己服务器上的情况,你不是用图床嘛?图床的话其实能在我的使用方法的基础上衍生出不同的用法的。

    其实并不了解你的实际需求,你要确定几件事情:
    1. 图片是存在自己的服务器上还是存在第三方服务上?
    2. 如果存在第三方服务上你是用图床还是 CDN ?
    3. 如果使用图床你是否还要用 CDN 来加速?

    个人觉得如果图少的话,比如只有自己博客文章的几张图,就直接放在自己服务器上,然后用我的方案使用 CDN 加速;
    如果图非常多,就像煎蛋网那样的,还不断上传新图的,那你可能就需要图床了,而且 CDN 加速的话最好选择按流量收费的 CDN 而不是按空间大小收费的 CDN 。
    libook
        18
    libook  
       2015-12-30 16:24:59 +08:00
    @XiaoXiaoNiWa 你要什么联系方式?邮箱?电话?微信?
    vikeria
        19
    vikeria  
       2015-12-30 16:37:22 +08:00 via Android
    @alian 同问 为什么是 307 呢

    base64 存进数据库,请求的时候是不是每次都会被认为是非静态资源,浏览器根本不会做缓存呢?
    libook
        20
    libook  
       2015-12-30 16:54:09 +08:00
    @alian @vikeria 请去制定 http 标准的 W3C 官方网站上看 http 状态码标准文档,顺便加个书签 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    原文是这么描述 307 的:
    ```
    10.3.8 307 Temporary Redirect

    The requested resource resides temporarily under a different URI. Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.

    The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) , since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the information necessary for a user to repeat the original request on the new URI.

    If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
    ```
    注意最后一段。
    我用 307 是因为我的静态资源链接以后有可能变化的,所以我进行“临时的重定向”,实际使用要根据状态码性质可具体需求来选择。
    icedx
        21
    icedx  
       2015-12-30 17:27:30 +08:00
    入库的有 我见过
    入库非常不值得 尤其是访问量大的时候
    vikeria
        22
    vikeria  
       2015-12-30 17:46:56 +08:00 via Android
    @libook 受教,已入书签
    TakanashiAzusa
        23
    TakanashiAzusa  
       2015-12-30 18:22:40 +08:00
    入库的话图片就不能多域名部署,而且静态资源入数据库。。我不知道你们怎么想的反正我觉得很可怕,你到时候数据库迁移什么的时候怎么办。。
    aivier
        24
    aivier  
       2015-12-30 18:26:55 +08:00
    我的图片体积最大的也不超过 100K...不担心这个问题,或者你可以考虑 lazyload ,就像淘宝那样
    XiaoXiaoNiWa
        25
    XiaoXiaoNiWa  
    OP
       2015-12-30 18:29:56 +08:00
    @TakanashiAzusa 联系运营方协助来迁移呢~
    @vikeria 博客更新周期较长(>一周),站点本身用 wpsupercache 做了静态缓存。所以获取的都是静态页面。
    @libook 邮箱吧~
    TakanashiAzusa
        26
    TakanashiAzusa  
       2015-12-30 18:41:27 +08:00
    @XiaoXiaoNiWa 喷了,你真可爱 你知道图片资源和正常的数据大小比区别有多少么。。可能一篇文章在数据库里占用的大小才几十 K ,几张图片就好几 M 了——不说迁移,先考虑下数据库备份的成本
    jin5354
        27
    jin5354  
       2015-12-30 19:21:56 +08:00
    图不加载完为啥不显示?图片加载又不是阻塞的,完全可以先渲染 dom 再显示图片,只是可能引起抖动(重绘)
    alian
        28
    alian  
       2015-12-30 20:31:19 +08:00
    @libook google 了一下不知在哪看到的哈哈,那个应该是错误的解释。。多谢详细的讲解,学习了!
    Silicon
        29
    Silicon  
       2015-12-31 03:07:01 +08:00 via Android
    base64 原理就是 3 个字节变成 4 个字节,不够的加 padding ,换句话说原来 1.5M 的文件做(且仅作) base64 编码之后是 2M 。直接传的话带宽压力反而上来了。

    但话说回来,变成 base64 后就是普通的文本文档,文本文档压缩还是不太困难的。

    楼主可以自己试一下。不过考虑到 CPU 占用也会加大,总体上的综合表现可能和常规方法差不多。在部分极端场景下或许是个有趣的方案。
    libook
        30
    libook  
       2015-12-31 11:17:41 +08:00
    @XiaoXiaoNiWa libook7atqqdotcom
    XiaoXiaoNiWa
        31
    XiaoXiaoNiWa  
    OP
       2015-12-31 13:47:36 +08:00
    @libook 谢谢。
    @Silicon 具体场景,具体分析:),适用于有图像审计系统的环境或情况。
    @TakanashiAzusa 谢谢! 这个方案的确有很多缺陷…应用环境有待考证。
    @jin5354 事实是导致了阻塞…很奇怪(
    jin5354
        32
    jin5354  
       2015-12-31 14:00:30 +08:00
    @XiaoXiaoNiWa 有例子没?链接啥的
    XiaoXiaoNiWa
        33
    XiaoXiaoNiWa  
    OP
       2016-01-01 13:24:49 +08:00
    @jin5354 例如我的博客…
    jin5354
        34
    jin5354  
       2016-01-01 13:47:37 +08:00
    @XiaoXiaoNiWa DNS_PROBE_FINISHED_NXDOMAIN...
    XiaoXiaoNiWa
        35
    XiaoXiaoNiWa  
    OP
       2016-01-02 15:08:48 +08:00
    @jin5354 访问挺正常啊~ aliyun 的 dns
    indust
        36
    indust  
       2016-01-02 18:09:26 +08:00
    @XiaoXiaoNiWa
    Registrar Status: redemptionPeriod
    _(:з」∠)_过期了没续费吧..
    XiaoXiaoNiWa
        37
    XiaoXiaoNiWa  
    OP
       2016-01-03 13:19:13 +08:00
    @indust @jin5354 新域名是 tap-io.com
    看来我忘记修改个人资料了 : (
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2759 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:26 · PVG 23:26 · LAX 07:26 · JFK 10:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.