洛阳便宜网站建设公司,精美网站设计,司法鉴定网站建设的内容,网站建设可信赖是这样的需求#xff0c;有一个web页面#xff0c;里面图片的上传和预览来自于一个独立的文件服务器#xff0c;对http的请求需要进行访问权限的设置#xff0c;就是在请求的header里加一个Authorization的字段。上传好说我用的Axios直接添加一个header就行了#xff0c;但… 是这样的需求有一个web页面里面图片的上传和预览来自于一个独立的文件服务器对http的请求需要进行访问权限的设置就是在请求的header里加一个Authorization的字段。上传好说我用的Axios直接添加一个header就行了但是预览就比较麻烦了因为img这个标签图片下载展示是浏览器自己实现的没有办法去修改。所以首先想到就是通过接口添加自定义header转发请求或者其他通过接口的方案了那怎么通过前端页面去实现这个功能首先声明的是这里用了一些新的API所以如果是一些比较老的浏览器那就没法这么做了。 问题分析img标签的src属性只能设置url不能设置这次请求的header。既然这样能不能通过别的方式先把图片下载下来然后再给img标签作展示相当于把src属性的下载和展示分成了两步先调用接口获取到了数据然后再把数据给展示出来也就是src里的值不是一个url地址而是一个数据流。 可以这样首先通过Object.defineProperty定义一个authSrc属性用来替换src属性的值然后在window.onload里等dom加载完以后去再下载图片。
!DOCTYPE html
html langen
headmeta charsetUTF-8titleProxy Image/titlescriptObject.defineProperty(Image.prototype, authsrc, {writable : true,enumerable : true,configurable : true})window.onload () {let img document.getElementById(img);let url img.getAttribute(authsrc);let request new XMLHttpRequest();request.responseType blob;request.open(get, url, true);request.setRequestHeader(Authorization, 凭证信息);request.onreadystatechange e {if (request.readyState XMLHttpRequest.DONE request.status 200) {img.src URL.createObjectURL(request.response);img.onload () {URL.revokeObjectURL(img.src);}}};request.send(null);}/script
/head
body
img width100 height100 idimg authsrchttp://threex.top/images/image_201909111450326.jpg
/body
/html 这样虽然可以实现功能但是每次还需要执行额外的脚本不能在Dom加载完的时候自动去下载展示不够优雅。能不能自动去下载展示呢 通过自定义元素加载 自定义元素不太了解的可以参考这里Using custom elements这里还有个w3c的草案autonomous-custom-element。
!DOCTYPE html
html langen
headmeta charsetUTF-8titleProxy Image/titlescriptlet requestImage function (url, element) {let request new XMLHttpRequest();request.responseType blob;request.open(get, url, true);request.setRequestHeader(Authorization, 凭证信息);request.onreadystatechange e {if (request.readyState XMLHttpRequest.DONE request.status 200) {element.src URL.createObjectURL(request.response);element.onload () {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});/script
/head
body
img width100 height100 isauth-imgauthSrchttp://threex.top/images/image_201909111450326.jpg
/body
/html 利用Node作请求转发 这里我是在Electron客户端用的是通过进程间通信的方式获取到了用户凭证信息如果是部署在服务器上的话应该使用其他方式。
let app http.createServer((request, response) {let config {host: xxx.com,method: GET,path: request.url,headers: {Authorization: 用户凭证}};let proxyRequest http.request(config, proxyResponse {proxyResponse.on(data, data {response.write(data, image/jpg);});proxyResponse.on(end, () {response.end();});response.writeHead(proxyResponse.statusCode, proxyResponse.headers);})request.on(data, data {proxyRequest.write(data, image/jpg);})request.on(end, () {proxyRequest.end();})
});app.listen(port, () {console.log(has start proxy server!);
}) 利用Nginx 既然作请求转发那Nginx自然也是可以的但是Nginx里添加header都是固定没法去修改想到了一个方式先请求一个地址携带token然后自定义一个变量去设置这个值。这个方式有点恶心一来是把token暴露了出来二来是容易造成误伤一不小心就把token更新了而且假如Nginx重启了这时候token也没了。只作为一个思路拓展了是不能这么搞的大概像下面这样。
server {...set $AUTH_TOKEN ;location /token/([0-9a-z])$ {set $AUTH_TOKEN $1;return 200;}location /image {proxy_pass http://xxx.com;proxy_set_header Authorization $AUTH_TOKEN;}
}