V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
scriptB0y
V2EX  ›  问与答

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

  •  
  •   scriptB0y · Jun 27, 2017 · 3010 views
    This topic created in 3231 days ago, the information mentioned may be changed or developed.

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

    我纠结了三天了。

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

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

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

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

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

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

    你这么说我确实觉得 post 符合语义一些
    otakustay
        20
    otakustay  
       Jun 28, 2017
    @scriptB0y 我倒觉得验证码的生成逻辑里完全没有这个 ticket 的参与,你说的相同图片其实是浏览器缓存导致的,比如 2 台不同的电脑用相同的 ticket 请求验证码,你能保证返回一样的码吗,能的话这就是给人作弊的后门
    lslqtz
        21
    lslqtz  
       Jun 28, 2017
    我倒认为是 GET。
    因为请求验证码的时候本地没有带上其它的用于生成或处理的信息,而单纯是由于服务端来处理的。。
    我纯当它是请求图片。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2622 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 120ms · UTC 14:52 · PVG 22:52 · LAX 07:52 · JFK 10:52
    ♥ Do have faith in what you're doing.