一道面试题,GET 请求能传图片吗?
发布于 2021-11-24 12:09 ,所属分类:2021面试经验技巧分享
「前言」
曾经遇到的面试题,觉得挺有意思,来说下我的答案及思考过程。
首先,我们要知道的是,图片一般有两种传输方式:base64
和file
对象。
base64 图片
图片的base64
编码想必大家都见过:
base64
的本质是字符串,而GET
请求的参数在url
里面,所以直接把图的base64
数据放到url
里面,就可以实现GET
请求传图片。
input
输入框拿到的图是file
对象,图片file
对象转base64
:
// img参数:file文件或者blob
constgetBase64=img=>{
returnnewPromise((resolve,reject)=>{
constreader=newFileReader();
reader.onload=e=>{
resolve(e.target.result);
};
reader.onerror=e=>reject(e);
reader.readAsDataURL(img);
})
}
问题来了,GET
请求的url
长度是有限制的,不同的浏览器长度限制不一样,最长的大概是 10k 左右,根据base64
的编码原理,base64
图片大小比原文件大小大 1/3,所以说base64
只能传一些非常小的小图,大图的base64
太长会被截断。但其实这个长度限制是浏览器给的,而不是GET
请求本身,也就说,在服务端,GET
请求长度理论上无限长,也就是可以传任意大小的图片。
file 对象
我们来看看这个场景:
<formaction="http://localhost:8080/"method="get">
<inputtype="file"name="logo">
<inputtype="submit">
</form>
选择图片,然后提交表单,能提交成功,但是接口收不到文件。请求的url
会变成http://localhost:8080/?logo=xxx.png
,但是不会携带图片数据。正常情况,file
对象数据是放在POST
请求的body
里面,并且是form-data
编码。那么GET
请求能否有body
体呢?答案是可以有。GET
和POST
并没有本质上的区别,他们只是HTTP
协议中两种请求方式,仅仅是报文格式不同(或者说规范不同)。做过底层开发的同事可能比较熟悉,之前我们C语言的同事和我讲,我们的HTTP
请求,他们收到是这样子的:
举个栗子, 一个普通的 GET 请求,他们收到是这样的:
GET/test/?sex=man&name=zhangsanHTTP/1.1
Host:http://localhost:8080
Accept:application/json,text/plain,*/*
Accept-Encoding:gzip,deflate
Accept-Language:zh-CN,zh;q=0.9
Connection:Keep-Alive
POST 请求长这样:
POST/addHTTP/1.1
Host:http://localhost:8080
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection:Keep-Alive
sex=man&name=Professional
同样,DELETE
、PUT
、PATCH
请求,也都是这样的报文。底层解析这个报文的时候,并不关心是什么请求,所以说GET
请求也可以有body
体,也可以传form-data
数据。有兴趣的可以拿 postman(我用的版本是 v7.30.1) 试一下,看看GET
请求传图片,接口能不能收到图片文件:
GET 请求能不能带 body 这个事是由 HTTP 协议来定义的
。所谓协议就是大家共同遵守的一套规则,你不遵守某一规则有时候确实不会有大问题,但是其行为表现是什么就不得而知了。协议带来规范化,规范化带来高效。事实是 HTTP 1.1 的 RFC 文档里没有禁止 GET 请求带 body ,但是也没有定义 GET 请求 body 的语义。
参见:tools.ietf.org
。
❝A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
❞
总结
作为面试题的话,本题大概有两个考点:
二进制图片序列化 base64; 特定场景的 url 长度限制。 部分 http 协议知识。
或者说,真要 get 传图片作为方案的话,需要打通上面两个关键技术问题。面试现场也可以再加一些Blob、TypedArray、图片压缩方案之类的。
END
欢迎gongzhong号
IDEA 注释模板这样搞,惊艳,又骚气!
相关资源