面试官:GET 能上传图片吗?
这个问题是我以前带过的实习生在面试的时候遇到的一道面试题,当我听到这个问题的时候我觉得挺有意思,下面我来解答一下这个问题吧。我们都知道图片有两种传输方式 base64 和 file 对象。base64 的本质是字符串,GET 请求的参数在 URL 中,因此直接把图的 base64 数据放到 URL 里是可以实现 GET 请求上传图片的。下面的代码就是将 file 对象转 base64 后上传的代码:
这就是答案吗?如果是这么认为的话,那我只能说你在面试官那里大概率是不通过的,这是为什么呢?因为 GET 请求的 URL 长度是有限的,不同浏览器对长度的限制是不一样的,最长也就大概是 10k 左右。但是根据 base64 的编码原理,图片 base64 的大小比原文件大了 1/3 左右,因此 base64 只能传一些非常小的小图,大图 base64 会被截断。
TIP:GET 长度限制是浏览器设定的,不是 GET 请求本身设定的,理论上 GET 请求长度是无限长的,是可以传任意大小的图片。
下面来看这个场景:
运行代码,选择图片并提交表单,虽然能提交成功,但接口收不到任何 文件。请求 URL 变成了http://127.0.0.1:8080/?img=xxx.jpg
,而且未携带图片数据。正常来说 file 对象数据是放在 POST 请求的 body 里,并且使用 form-data 编码。那么我们可以想像 GET 请求是否有 body 呢?答案是有的。GET 和 POST 没有本质上的区别,只是 HTTP 协议的两种请求方式,只是报文规范不同。一个普通的 GET 请求,收到请求是这样的:
POST 请求是这样:
底层解析报文时并不关心是什么请求,因此 GET 请求也有 body,可以传 form-data 数据。GET 请求能不能带 body 是 HTTP 协议来定义的。协议是共同遵守的规则,它带来规范和高效。在 HTTP 1.1 的 RFC 文档里并没有禁止 GET 请求携带 body,但也没有定义 GET 请求 body 的语义。这道面试题主要是考察二进制图片转换成 base64、特定场景的 URL 长度的限制以及 HTTP 知识。
评论