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

2017-06-27 20:18:24 +08:00
 scriptB0y

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

我纠结了三天了。

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

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

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

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

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

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

你这么说我确实觉得 post 符合语义一些
otakustay
2017-06-28 12:22:26 +08:00
@scriptB0y 我倒觉得验证码的生成逻辑里完全没有这个 ticket 的参与,你说的相同图片其实是浏览器缓存导致的,比如 2 台不同的电脑用相同的 ticket 请求验证码,你能保证返回一样的码吗,能的话这就是给人作弊的后门

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/371494

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX