天天看點

#yyds幹貨盤點#面試官:GET能上傳圖檔嗎?

這個問題是我以前帶過的實習生在面試的時候遇到的一道面試題,當我聽到這個問題的時候我覺得挺有意思,下面我來解答一下這個問題吧。 我們都知道圖檔有兩種傳輸方式base64和file對象。base64的本質是字元串,GET 請求的參數在URL中,是以直接把圖的base64資料放到URL裡是可以實作GET請求上傳圖檔的。下面的代碼就是将file對象轉base64後上傳的代碼:

//img參數類型為圖檔檔案或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請求的URL長度是有限的,不同浏覽器對長度的限制是不一樣的,最長也就大概是 10k左右。但是根據base64的編碼原理,圖檔base64的大小比原檔案大了1/3左右,是以base64隻能傳一些非常小的小圖,大圖base64會被截斷。

TIP:GET長度限制是浏覽器設定的,不是GET請求本身設定的,理論上GET請求長度是無限長的,是可以傳任意大小的圖檔。

下面來看這個場景:

<form action="http://127.0.0.1:2022/" method="get">
    <input type="file" name="img">
    <input type="submit">
</form>      
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 /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