字節(jié)二面:GET 請(qǐng)求能上傳圖片嗎?我蒙了
前言
曾經(jīng)遇到的面試題,覺得挺有意思,來說下我的答案及思考過程。
首先,我們要知道的是,圖片一般有兩種傳輸方式:base64和file對(duì)象。
base64 圖片
圖片的base64編碼想必大家都見過:
base64的本質(zhì)是字符串,而GET請(qǐng)求的參數(shù)在url里面,所以直接把圖的base64數(shù)據(jù)放到url里面,就可以實(shí)現(xiàn)GET請(qǐng)求傳圖片。
input輸入框拿到的圖是file對(duì)象,圖片file對(duì)象轉(zhuǎn)base64:
- // img參數(shù):file文件或者blob
 - const getBase64 = img => {
 - return new Promise((resolve,reject) => {
 - const reader = new FileReader();
 - reader.onload = e => {
 - resolve(e.target.result);
 - };
 - reader.onerror = e => reject(e);
 - reader.readAsDataURL(img);
 - })
 - }
 
問題來了,GET請(qǐng)求的url長(zhǎng)度是有限制的,不同的瀏覽器長(zhǎng)度限制不一樣,最長(zhǎng)的大概是 10k 左右,根據(jù)base64的編碼原理,base64圖片大小比原文件大小大 1/3,所以說base64只能傳一些非常小的小圖,大圖的base64太長(zhǎng)會(huì)被截?cái)唷?/p>
但其實(shí)這個(gè)長(zhǎng)度限制是瀏覽器給的,而不是GET請(qǐng)求本身,也就說,在服務(wù)端,GET請(qǐng)求長(zhǎng)度理論上無限長(zhǎng),也就是可以傳任意大小的圖片。
file 對(duì)象
我們來看看這個(gè)場(chǎng)景:
- <form action="http://localhost:8080/" method="get">
 - <input type="file" name="logo">
 - <input type="submit">
 - </form>
 
選擇圖片,然后提交表單,能提交成功,但是接口收不到文件。請(qǐng)求的url會(huì)變成http://localhost:8080/?logo=xxx.png,但是不會(huì)攜帶圖片數(shù)據(jù)。正常情況,file對(duì)象數(shù)據(jù)是放在POST請(qǐng)求的body里面,并且是form-data編碼。
推薦一個(gè) Spring Boot 基礎(chǔ)教程及實(shí)戰(zhàn)示例:https://github.com/javastacks/spring-boot-best-practice
那么GET請(qǐng)求能否有body體呢?
答案是可以有。
GET和POST并沒有本質(zhì)上的區(qū)別,他們只是HTTP協(xié)議中兩種請(qǐng)求方式,僅僅是報(bào)文格式不同(或者說規(guī)范不同)。
做過底層開發(fā)的同事可能比較熟悉,之前我們C語言的同事和我講,我們的HTTP請(qǐng)求,他們收到是這樣子的:
舉個(gè)栗子, 一個(gè)普通的 GET 請(qǐng)求,他們收到是這樣的:
- GET /test/?sex=man&name=zhangsan HTTP/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 請(qǐng)求長(zhǎng)這樣:
- POST /add HTTP/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請(qǐng)求,也都是這樣的報(bào)文。底層解析這個(gè)報(bào)文的時(shí)候,并不關(guān)心是什么請(qǐng)求,所以說GET請(qǐng)求也可以有body體,也可以傳form-data數(shù)據(jù)。
有興趣的可以拿 postman 試一下,看看GET請(qǐng)求傳圖片,接口能不能收到圖片文件:
結(jié)尾
綜上所述,GET 請(qǐng)求是可以傳圖片的,但是 GET 和 POST 的規(guī)范還是要遵守的,如果有后臺(tái)讓你這么做,錘他就行了!


















 
 
 














 
 
 
 