img标签请求 添加自定义header(一)
需求场景:上传图片后接口返回文件id
,展示图片时链接地址为/file/preview?id=xxx
。但系统中的接口都需要鉴权(即在请求header
中添加authCode
),而img
标签的请求是浏览器的默认行为,并不受我们的接口拦截(如axios
请求拦截)约束。
通常的解决方式:
手动发请求+处理流
以Vue
为例,我们可以封装一个自定义图片组件authImg
<template><img ref="img">
</template>
<script>
export default {props:{src:{type: String,default:''}},watch:{src:{handler(n){if(n){this.getImage(n);}},immediate:true}},methods:{getImage(url){let that = this;that.$nextTick(()=>{let request = new XMLHttpRequest();request.responseType = 'blob';request.open('get', url, true);// 添加自定义请求头request.setRequestHeader('authToken', localStorage.getItem('authToken')); request.onreadystatechange = e => {if (request.readyState == XMLHttpRequest.DONE && request.status == 200) { that.$refs.img.src = URL.createObjectURL(request.response);that.$refs.img.onload = () => {that.$refs.img && URL.revokeObjectURL(that.$refs.img.src);} }};request.send(null);});}}
}
</script>
使用:
<template><authImg src="/file/preview?id=xxx"></authImg>
</template>
此方式可以处理绝大多数场景,但解决不了类似富文本中的img
问题。一般富文本会保存成字符串,数据回显时,很难处理其中的img
标签
通过自定义元素加载
这种方式就是扩展原有的HTML Element
,实现一些自定义的功能,示例如下
// 扩展原生Image
let requestImage = function (url, element) {let request = new XMLHttpRequest();request.responseType = 'blob';request.open('get', url, true);request.setRequestHeader('authToken', localStorage.getItem('authToken')); request.onreadystatechange = e => {if (request.readyState == XMLHttpRequest.DONE && request.status == 200) {element.src = URL.createObjectURL(request.response);element.onload = () => {element && URL.revokeObjectURL(element.src);}}};request.send(null);
}class AuthImg extends HTMLImageElement {constructor() {super();this._lastUrl = '';}static get observedAttributes() {return ['authsrc'];}connectedCallback() {let url = this.getAttribute('authsrc');if (url !== this._lastUrl) {this._lastUrl = url;requestImage(url, this);}console.log('connectedCallback() is called.');}
}
window.customElements.define('auth-img', AuthImg, {extends: 'img'});
使用:
原始(报错401):<img src="/file/preview?id=xxx">
替换后:<img is="auth-img" authsrc="/file/preview?id=xxx"/>
此方式可以解决上述的富文本中的图片问题,以wangEdit
为例
// 自定义上传图片
this.editor.customConfig.uploadImgHooks = {customInsert: function (insertImg, result, editor) {let imgUrl = result.data[0];that.editor.cmd.do('insertHTML', `<img is="auth-img" authsrc="${imgUrl}" alt="图片" /> `);}
}
serviceWorker
我们真的没办法拦截到浏览器原生的img
请求吗?其实是可以的。serviceWorker
具体使用可自行查找资料,这里我们简单做个示例:
<!--index.html-->
<script>
if ('serviceWorker' in navigator) {navigator.serviceWorker.register('./sw.js');
}
</script>
//sw.js
self.addEventListener('fetch', function (evt) {// 拦截指定请求前缀if (evt.request.url.indexOf('image/view?id')>-1) {// 拷贝原始请求const request = evt.request.clone();// 创建headersconst headers = new Headers();// 添加自定义请求头headers.append('authToken', '7c5c90e6-bf49-47c0-bda1-bc93255364d8'); // 创建新请求const newRequest = new Request(request,{headers,mode: 'cors'})// 返回=>走浏览器原有逻辑evt.respondWith(fetch(newRequest))}
});
这样我们就不需要修改img
标签,或者做其它处理。通过serviceWorker
自动拦截对应请求,添加请求头,剩下的交给浏览器就可以了。
后记
第一、二种方式原则上差不多,第二种覆盖场景会多一些,但改动量都比较大。
第三种方式改动较小,基本上是全场景覆盖,如富文本,如css
背景图设置成接口地址;但自定义性较差,比如异常回调,加loading
之类的操作。
当然使用serviceWorker
,同样可以对以window.open
或者window.location.href
形式的下载链接拦截,添加自定义请求头,就不需要前端通过调用接口获取文件流再手动转换了。
img标签请求 添加自定义header(一)相关推荐
- 如何给img标签里的请求添加自定义header
是这样的需求,有一个web页面,里面图片的上传和预览来自于一个独立的文件服务器,对http的请求需要进行访问权限的设置,就是在请求的header里加一个Authorization的字段.上传好说我用的 ...
- img标签请求拦截_如何给img标签里的请求添加自定义header?
是这样的需求,有一个web页面,里面图片的上传和预览来自于一个独立的文件服务器,对http的请求需要进行访问权限的设置,就是在请求的header里加一个Authorization的字段.上传好说我用的 ...
- 如何给img标签里的请求的添加自定义header
如何给img标签里的请求添加自定义header 是这样的需求,有一个web页面,里面图片的上传和预览来自于一个独立的文件服务器,对http的请求需要进行访问权限的设置,就是在请求的header里加一个 ...
- 前端cookie 放到请求头_ajax请求携带cookie和自定义请求头header(跨域和同域)
错误: 1.ajax请求时是不会自动带上cookie的,要是想让他带上的话,必须设置withCredential为true. 正确: 1.ajax同域请求下,ajax会自动带上同源的cookie: 2 ...
- vue中a标签实现带header的下载
简单介绍一下,这个是想用a标签请求接口下载文件,请求接口动态添加header请求头 1.在按钮上添加点击事件 <el-button type="backinfo" size= ...
- http请求报头header
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 http 请求报头header 一.认识请求报头(header) 1.Host 2.content-length 3.content- ...
- java http head 请求_http请求头header、请求体body、请求行介绍
HttpServletRequest对象代表客户端的请求,当客户端通过http协议请求访问 服务器的时候,http请求头的所有信息都封装在这个对象中,通过这个对象,可以获取客户端请求的所有信息.htt ...
- 解决通过Nginx转发的服务请求头header中含有下划线的key,其值取不到的问题
解决通过Nginx转发的服务请求头header中含有下划线的key,其值取不到的问题 参考文章: (1)解决通过Nginx转发的服务请求头header中含有下划线的key,其值取不到的问题 (2)ht ...
- php 打印curl请求的header信息和返回的header信息
1.打印curl请求的header信息 在执行curl请求curl_exec($ch)前的代码中,添加如下配置: //设置为true时追踪句柄的请求字符串,从 PHP 5.1.3 开始支持,就是允许你 ...
最新文章
- python 十大经典排序算法
- 解决dubbo问题:forbid consumer(2)
- 制约RFID在包装领域的规模应用的障碍盘点
- Jquery给基本控件的取值、赋值
- netapp学习(五)---创建volume
- tr69 GatewayInfo 节点添加
- linux path 文件,linux基础,文件目录管理,PATH,cp,mv,cat
- 关于React的一切(updating...)
- 浅谈技术管理之个体能力建设
- [转载]IEEE754标准的浮点数表示
- 阻塞与非阻塞都是什么呢?
- 向iis注册framework命令
- html 可换行属性,html里title属性换行的方法
- 像中文的罗马音字体复制_罗马音字体复制下载
- 双系统中Ubuntu启动失败
- android tv 盒子,安卓TV电视盒子推荐软件一览表(盒子端+手机端+电脑端+群晖端)...
- mac:系统存在两个Macintosh HD是怎么回事
- php容器概念,PHP容器——Pimple运行流程浅析
- 【HEOI2013】bzoj3168 钙铁锌硒维生素
- 洛谷 P4544 [USACO10NOV]Buying Feed G)(单调队列优化DP)
热门文章
- 开课吧:未来人工智能发展前景如何呢?
- 批量提取文件夹中文件 目录、文件名、大小(备忘)
- 设计一个接口, 并设计一个实现类实现该接口,演示它们的使用。具体,创建一个名称为Person的接口,在接口中定义两个方法sayHello()和sayBye()。
- win10连接共享打印机。同时解决电脑出现“你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访
- 论文解读:门控时钟的gating ratio如何提升
- 自学Node--回调地狱
- 【PIC单片机】2.编译器下载
- Climbing-stairs
- 解网鼎杯一道web题(fakebook)
- canvas图片文字合成(小程序分享)