前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >利用 img 的 src 属性发起 get 请求踩坑记录

利用 img 的 src 属性发起 get 请求踩坑记录

作者头像
玖柒的小窝
修改于 2021-10-25 02:35:32
修改于 2021-10-25 02:35:32
4.6K00
代码可运行
举报
文章被收录于专栏:各类技术文章~各类技术文章~
运行总次数:0
代码可运行

一、背景

工作中,碰到一个需求,需要使用img标签的src属性发送一个get请求。原先的设想是,当请求发送成功之后,会触发imgonload回调,请求失败,则触发imgonerror回调。奈何理想很丰满,现实很骨感...

二、实践

1. 编写测试demo

首先写一个demo,利用js动态创建一个img标签,然后将接口地址赋值给src属性,发起请求,同时,设置好onloadonerror回调函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
    window.onload = function() {
      const img = document.createElement('img')
  		img.onload = function(e) {
        console.log(e, 'success')
      }
      img.onerror = function(e) {
        console.log(e, 'fail')
      }
      img.src = 'http://localhost:3000/get'
      img.style.width = '100px'
      img.style.height = '100px'
      img.style.display = 'none'
   
      document.body.appendChild(img)
    }
  </script>
</body>
</html>
复制代码

这里是自己用express 写了一个简单的get请求接口来协助测试,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const express = require('express')

const app = express()

app.get('/get', function(request, response){
       
  const data = {
    'name':'张三',
    'age': 24
  }

  console.log(data)
  response.json(data)
})

app.listen(3000, () => {
  console.log('http://localhost:3000/get')
})
复制代码
2. 测试结果

​ 经过测试发现,即使请求成功,也无法触发imgonload回调,不管请求成功还是失败(接口主动抛出错误让请求失败,或者请求一个不存在的接口让请求失败),都是触发的onerror回调。并且浏览器会抛出一个警告:

Cross-Origin Read Blocking (CORB) blocked cross-origin response http://localhost:3000/get with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

​ 结合onload的定义(onload 事件在图片加载完成后立即执行)可以发现,请求确实是成功了,并且返回了数据,但是img无法处理除图片之外的数据格式,所以始终无法触发onload回调,即使请求是成功的。而当你把src属性的值换成一个正常的图片地址后,onload就能正常触发。

3. 再次尝试,失败告终

​ 因为img只能单向发送get请求,不能访问响应内容,所以本来想通过onloadonerror来判断请求成功还是失败,现在看来,完全不可行。但是不甘心呀,于是网上查阅资料,发现还HTMLImageElement上还有一个叫complete的只读属性,它是一个布尔值,表示图片是否完全加载完成。在看到定义里面表示图片是否完全加载完成的时候,心凉了一截,怕是这个也没办法达到我的要求,但还是抱着试一试的想法测试了一下,于是在原先的代码里,添加了complete属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript">
    window.onload = function() {
      const img = document.createElement('img')
  		img.onload = function(e) {
        console.log(e, 'success')
        console.log(img.complete)
      }
      img.onerror = function(e) {
        console.log(e, 'fail')
        console.log(img.complete) // true
      }
      img.src = 'http://localhost:3000/get'
      img.style.width = '100px'
      img.style.height = '100px'
      img.style.display = 'none'
   		
   		console.log(img.complete) // false
   		
      document.body.appendChild(img)
    }
  </script>
</body>
</html>
复制代码

​ 结果发现,不管请求成功还是失败,都是触发的onerror,而onerror里面打印的complete值也都是true,王德发???定义不是说当图片完全加载完成complete的值才为true的吗?你要是请求成功时为true也就算了,请求失败也是true,我不理解呀,是我姿势不对吗?如果有大神路过,希望能帮忙解答一下,小弟在此谢谢了!

​ 综上所述,特以此文章记录

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验