V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
scriptB0y
V2EX  ›  问与答

访问验证码图片用什么 HTTP 方法才符合语义?

  •  
  •   scriptB0y · 2017-06-27 20:18:24 +08:00 · 2534 次点击
    这是一个创建于 2708 天前的主题,其中的信息可能已经有所发展或是发生改变。

    讲道理 GET 应该是幂等的,而一般的验证码都是设计成访问一次就改变了的(服务器 session 存储的也改,这是“看不清楚”的 feature ),那么问题来了,感觉用 GET 不合适,因为很明显不是幂等的,但却又的确是一个“访问请求”( GET 的字面意思)。

    我纠结了三天了。

    21 条回复    2017-06-28 21:01:33 +08:00
    whypool
        1
    whypool  
       2017-06-27 20:39:43 +08:00
    肯定走 get,首先是渲染,后端返回的验证码走的是文件流,前端拿到的是一个字符串,用 img 标签浏览器直接就解析成图片了,如果用 POST 什么的,还得前端用 js 去转一次字符串再添加到页面上,这肯定比浏览器直接渲染慢
    scriptB0y
        2
    scriptB0y  
    OP
       2017-06-27 20:45:34 +08:00
    @whypool 理由不成立,post 请求也可以拿回一个字符串 url 直接用 img 标签填上。GET 和 POST 方法除了语义不同没有别的区别。
    whypool
        3
    whypool  
       2017-06-27 20:56:28 +08:00
    @scriptB0y 想多了,你 post 就走了 2 次请求,首先是 post 拿字符串接口,然后是拼接 img 的 url,再 append 到页面上,新的 img 带了 url 属性,浏览器会发一个 get 请求
    binux
        4
    binux  
       2017-06-27 20:57:33 +08:00   ❤️ 2
    你 get 的时候带一个时间戳不就是「幂等」的了吗
    lightening
        5
    lightening  
       2017-06-27 21:06:15 +08:00
    这是个好问题……关注一下
    littleylv
        6
    littleylv  
       2017-06-27 21:20:11 +08:00
    @whypool #3
    针对:
    “新的 img 带了 url 属性,浏览器会发一个 get 请求”
    这点我有疑惑。如果字符串是 base64 的编码呢?应该不会请求了吧(我猜测的。但是我印象中浏览器 F12 的 Network 里会有记录,但不知道会不会从服务端请求)

    当然我是赞同用 GET 的。
    Jaylee
        7
    Jaylee  
       2017-06-27 21:21:33 +08:00   ❤️ 1
    典型的书读的不多而想得太多
    yidinghe
        8
    yidinghe  
       2017-06-27 21:42:10 +08:00 via Android
    我觉得“等幂”这个词发明出来就是为了和“等同”相区分。
    jarlyyn
        9
    jarlyyn  
       2017-06-27 21:47:21 +08:00 via Android
    Get 必须幂等什么鬼

    楼主做获取服务器当前时间的接口怎么办?
    scriptB0y
        10
    scriptB0y  
    OP
       2017-06-27 22:03:24 +08:00
    @jarlyyn 这个和时间不一样吧,如果说时间是服务器的一种资源的话,那么这个资源是服务器上自己改变的,并不是因为 GET 请求而改变的,就想天气资源一样。

    但是验证码作为服务器的资源的话,却会因为你的访问而改变,而不是自己发生的变化。
    scriptB0y
        11
    scriptB0y  
    OP
       2017-06-27 22:04:05 +08:00
    @binux 你是说对一个时间戳生成的验证码永远是一样的?
    scriptB0y
        12
    scriptB0y  
    OP
       2017-06-27 22:05:12 +08:00
    @whypool post 和 get 一样的,如果是 get 不也是两个请求吗?第一个 get 请求获得了 img 的 url (也就是页面的 document ),第二次发送图片。

    或者说 post 直接拿回 base64 文件内容?

    总之重点在语义。
    scriptB0y
        13
    scriptB0y  
    OP
       2017-06-27 22:08:27 +08:00
    @binux 我觉得时间戳这个靠谱,相当于带一个 ticket
    tinyproxy
        14
    tinyproxy  
       2017-06-28 07:18:54 +08:00 via iPhone
    这种问题纠结 3 天。。。你就不能去看看其他站点是怎么做的么,这又不是啥核心代码,闭门造车大忌啊
    scriptB0y
        15
    scriptB0y  
    OP
       2017-06-28 09:14:24 +08:00
    @tinyproxy 倒不是自己要写,就是胡思乱想啦。其他网站都是用 get,只是想到这个问题而已
    oott123
        16
    oott123  
       2017-06-28 09:29:00 +08:00 via Android
    做成每次访问都出同一个图片的验证码就幂等了(逃
    otakustay
        17
    otakustay  
       2017-06-28 10:06:28 +08:00
    你真要谈语义,验证码显然不是 GET,因为这个资源是请求时才真正创建(并通常持久化在 Session 中)的,所以是 POST
    otakustay
        18
    otakustay  
       2017-06-28 10:07:02 +08:00
    @scriptB0y 验证码的逻辑是时间戳一样的情况下返回相同的图片?
    scriptB0y
        19
    scriptB0y  
    OP
       2017-06-28 12:03:15 +08:00
    @otakustay 验证码这个可以精确到毫秒,然后作为一个 ticket (可以和其他字符串混合加密一下),一样的情况下返回相同的图片,然后让 ticket 只能用一次。

    你这么说我确实觉得 post 符合语义一些
    otakustay
        20
    otakustay  
       2017-06-28 12:22:26 +08:00
    @scriptB0y 我倒觉得验证码的生成逻辑里完全没有这个 ticket 的参与,你说的相同图片其实是浏览器缓存导致的,比如 2 台不同的电脑用相同的 ticket 请求验证码,你能保证返回一样的码吗,能的话这就是给人作弊的后门
    lslqtz
        21
    lslqtz  
       2017-06-28 21:01:33 +08:00
    我倒认为是 GET。
    因为请求验证码的时候本地没有带上其它的用于生成或处理的信息,而单纯是由于服务端来处理的。。
    我纯当它是请求图片。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:40 · PVG 04:40 · LAX 12:40 · JFK 15:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.