灵魂拷问:GET 请求能传图片吗?

点击上方“程序员黑叔”,选择“置顶或者星标”

你的关注意义重大!

作者:沉末_

https://juejin.im/post/6860253625030017031

前言

曾经遇到的面试题,觉得挺有意思,来说下我的答案及思考过程。

首先,我们要知道的是,图片一般有两种传输方式:base64 和 file对象。

base64 图片

图片的base64编码想必大家都见过:

base64 的本质是字符串,而 GET 请求的参数在 url 里面,所以直接把图的 base64 数据放到 url 里面,就可以实现 GET 请求传图片。

input 输入框拿到的图是 file 对象,图片 file 对象转 base64 :

// img参数: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 请求的 url 长度是有限制的,不同的浏览器长度限制不一样,最长的大概是 10k 左右,根据 base64 的编码原理,base64图片大小比原文件大小大 1/3,所以说 base64 只能传一些非常小的小图,大图的 base64 太长会被截断。但其实这个长度限制是浏览器给的,而不是 GET 请求本身,也就说,在服务端,GET 请求长度理论上无限长,也就是可以传任意大小的图片。

file 对象

我们来看看这个场景:

<form action="http://localhost:8080/" method="get">
    <input type="file" name="logo">
    <input type="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=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 请求长这样:

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 

同样,DELETEPUTPATCH 请求,也都是这样的报文。底层解析这个报文的时候,并不关心是什么请求,所以说 GET请求也可以有body 体,也可以传 form-data 数据。有兴趣的可以拿 postman 试一下,看看 GET 请求传图片,接口能不能收到图片文件:

结尾

综上所述,GET 请求是可以传图片的,但是 GET 和 POST 的规范还是要遵守的,如果有后台让你这么做,锤他就行了!

最后

  1. 我是黑叔,关注我,跑得更快噢!


亲,点这涨工资 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Python的`requests`库来发送POST请求并上图片。以下是一个示例代码: ```python import requests url = 'http://example.com/upload' image_path = 'path/to/image.jpg' # 打开图像文件并读取二进制数据 with open(image_path, 'rb') as image_file: image_data = image_file.read() # 设置请求头部,指定Content-Type为multipart/form-data headers = {'Content-Type': 'multipart/form-data'} # 创建请求体,包括要上的文件数据 files = {'file': image_data} # 发送POST请求 response = requests.post(url, headers=headers, files=files) # 检查响应状态码 if response.status_code == 200: print('图片成功!') else: print('图片失败。') ``` 在上述代码中,你需要将`url`替换为你要上图片的目标URL。`image_path`变量表示你本地图片文件的路径,根据实际情况进行修改。通过`open`函数打开图像文件,并使用`rb`模式以二进制方式读取文件数据。然后,构建请求头部,设置`Content-Type`为`multipart/form-data`,表示这是一个包含文件数据的表单请求。接下来,创建一个字典类型的`files`变量,将要上的文件数据放入其中,并使用`requests.post`方法发送POST请求。最后,你可以检查响应的状态码来确认图片是否成功上。 注意:这只是一个基本的示例代码,实际应用中可能需要根据具体的接口要求调整代码。另外,确保你的服务器端能够正确处理接收到的图片数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值