文件、blob
文件下载失败,将Blob对象转换为Json,处理异常错误?
捕获异常:
/** 导出文件流成功失败分别干干什么 * @param {String} res 文件流或者JSON对象(错误情况下) * @param {Boolean} blob res资源是否是blob对象,文件流 默认不传递该参数 * * */ export function downStreamCheck(res, blob) { let result = {}; return new Promise((resolve, reject) => { let reader = new FileReader(); reader.onload = e => { try { result = JSON.parse(e.target.result); } catch (e) { // console.log(e) } finally { if (typeof result.code !== 'undefined') { // 返回错误对象 Message({ message: result.message, type: 'error', duration: 5 * 1000 }); } else { resolve(); } } } if (!blob) { reader.readAsText(new Blob([res.data], { type: 'application/octet-stream' })); } else { reader.readAsText(res.data); } }) }
调用方式:
this.downStreamCheck(result).then(() => { //导出文件成功后的操作 this.result=result; })
问题地址:处理文件下载失败,如何将Blob对象转换为Json?
模拟a标签实现接口下载
如果返回的正常的文件流一般模拟a标签实现下载,如下:
/** * @param {String} resource 文件流 * @param {String} fileType 文件类型 * @param {String} fileName 文件名 (可以响应头部读取文件名,如下) * let resultFileName = res.headers['content-disposition']; * let name = resultFileName.substring(resultFileName.indexOf('=')).substring(1); * 使用方式 this.$downloadBlob(data,'application/octet-stream','download.zip');其中文件名可以从响应头截取 * * */ export function downloadBlob(resource, fileType, fileName) { var data = new Blob([resource], { type: fileType }); if ('download' in document.createElement('a')) { //非IE var downloadUrl = window.URL.createObjectURL(data); var anchor = document.createElement("a"); anchor.href = downloadUrl; anchor.download = fileName; anchor.style.display = 'none'; document.body.appendChild(anchor); anchor.click(); window.URL.revokeObjectURL(anchor.href); document.body.removeChild(anchor); } else { //IE10+下载 navigator.msSaveBlob(data, fileName); } }
获取响应头部返回的文件名
一般下载的文件都需要从响应头部读取文件名,如下代码:
/** 从响应头部读取文件名称 * @param {res} response * */ export function responseFileName(res) { if (res && res.headers) { let resultFileName = decodeURI(res.headers['content-disposition']); return resultFileName.substring(resultFileName.indexOf('=')).substring(1); } return ''; }
上面三个函数一般综合起来一起使用,下面vue使用方式,代码把三个方法注册到了全局,如下:
packetDownload(params).then((res) => { this.$downStreamCheck(res).then(() => { let fileName = this.$responseFileName(res); this.$downloadBlob(res.data,'application/octet-stream',fileName); }) })
cookie、缓存、跨域通讯、XSS
设置二级域名cookie共享
也即是把cookie的domain设置为顶级域名。
function getdomain(){ var domain = document.domain; var ip = /^(d+).(d+).(d+).(d+)$/; if(ip.test(domain)){ return domain; }else{ return document.domain.split('.').slice(1).join('.'); } } var firstDomainName = getdomain(); document.cookie="userid=888abc;domain="+firstDomainName+";path=/";
前端强制页面不缓存no-cache、no-store
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" />
日期相关
实现周的切换(上一周、下一周)
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"> <style> .con{overflow: hidden;} .same,#time{float:left;} #time{ width: 260px; text-align: center; } </style> </head> <body> <div class="con"> <button class="same" id="last-week">前一周</button> <div id="time"></div> <button class="same" id="next-week">下一周</button> </div> <script type="text/javascript" src="js/jquery-1.11.3.min.js"></script> <script type="text/javascript"> var currentFirstDate; var startTime = ''; var endTime = ''; function formatDate(date,joinStr){ if(joinStr) { return date.getFullYear()+ joinStr + (date.getMonth()+1)+ joinStr + date.getDate(); } else { return date.getFullYear()+'年' + (date.getMonth()+1)+'月' + date.getDate()+'日'; } } function addDate(date,n) { date.setDate(date.getDate()+n); return date; } function setDate(date) { var week = date.getDay()-1; date = addDate(date,week*-1); currentFirstDate = new Date(date); var str = formatDate(date) + '-' + formatDate(addDate(date,6)); startTime = formatDate(addDate(date,-6),'-'); endTime = formatDate(addDate(date,6),'-'); $('#time').html(str); } function ajaxlist() { } $(function() { setDate(new Date()); ajaxlist(); $('#last-week').on('click',function() { setDate(addDate(currentFirstDate,-7)); // 接口请求 ajaxlist(); }) $('#next-week').on('click',function() { setDate(addDate(currentFirstDate,7)); // 接口请求 ajaxlist(); }) }) </script> </body> </html>
事件
通过事件捕获实现登录拦截思路demo
document.addEventListener('click',function(event){ if(event.target.tagName.toLowerCase() == 'a') { // 在此阶段可以判断是否登录,未登录进行阻止捕获 if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } } },true);
HTML5相关
canvas绘制文本内容自动换行
/** canvas中的文字字段断行 * @param {String} textContent 绘制的文本内容 * @param {Number} textMaxWidth 每行文本的最大宽度 * @param {Number} drawX 绘制文本的x坐标 * @param {Number} drawY 绘制文本的y坐标 * @param {Number} lineHeight 文本之间的行高 * @param {Number} lineNum 最多绘制的行数 超过设置的行数..展示, 不设置此参数自动往下断行 * * */ function textBrokenLine(textContent,textMaxWidth,drawX,drawY,lineHeight,lineNum) { // 创建canvas var canvas = document.createElement('canvas'); canvas.id = 'canvas'; document.body.appendChild(canvas); var ctx = canvas.getContext('2d'); ctx.font = "14px 微软雅黑"; ctx.fillStyle = 'black'; if(ctx.measureText(textContent).width <= textMaxWidth) { ctx.fillText(textContent,drawX,drawY); } else { var drawTxt = ''; // 当前绘制的内容 var drawIndex = 0; // 当前绘制内容的索引 var drawLine = 1; // 第几行开始绘制 for(var i = 0; i < textContent.length; i++) { drawTxt += textContent[i]; if(ctx.measureText(drawTxt).width >= textMaxWidth) { if(lineNum) { // 有最多展示几行的参数进行特殊处理 if (drawLine >= lineNum) { ctx.fillText(textContent.substring(drawIndex, i) + '..', drawX, drawY); break; } else { ctx.fillText(textContent.substring(drawIndex, i + 1), drawX, drawY); drawIndex = i + 1; drawLine += 1; drawY += lineHeight; drawTxt = ''; } } else { ctx.fillText(textContent.substring(drawIndex, i + 1), drawX, drawY); drawIndex = i + 1; drawY += lineHeight; drawTxt = ''; } } else { // 内容绘制完毕,但是剩下的内容宽度不到textMaxWidth if (i === textContent.length - 1) { ctx.fillText(textContent.substring(drawIndex),drawX,drawY); } } } } // 获取canvas转化结果base64 var canvasDom = document.getElementById("canvas"); canvasDom.style.border = "red 1px solid"; var base64 = canvasDom.toDataURL("image/png"); console.log(base64); // canvasDom.parentNode.removeChild(canvasDom); } // 调用 textBrokenLine('这是用户输入的一段文字,这是用户输入的一段文字,这是用户输入的一段文字',100,0,20,20);
其它
获取IE浏览器版本
function IEVersion(){ var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器 var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; if(isIE) { userAgent.match(/MSIE (d+.d+);/g); var fIEVersion = parseFloat(RegExp["$1"]); if(fIEVersion == 7) { return 7; } else if(fIEVersion == 8) { return 8; } else if(fIEVersion == 9) { return 9; } else if(fIEVersion == 10) { return 10; } else { return 6;//IE版本<=7 } } else if(isEdge) { return 'edge';//edge } else if(isIE11) { return 11; //IE11 }else{ return -1;//不是ie浏览器 } }
JS跳转到app store内应用下载页面
跳转到应用商店:
(https)|(itms-apps)://itunes.apple.com/app/id{appID}
跳转到撰写评价:
(https)|(itms-apps)://itunes.apple.com/app/id{appID}?action=write-review
跳转到查看评价:
(https)|(itms-apps)://itunes.apple.com/app/viewContentsUserReviews?id={appID}
手机端和pc端均可适用。
示例代码:
window.location.href = 'itms-apps://itunes.apple.com/app/id414478124?action=write-review'
h5 JS判断是安卓还是ios设备,跳转到对应的下载地址
;(function(){
var u = navigator.userAgent;
var ua = navigator.userAgent.toLowerCase();
var dom = document.getElementById('btn');
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if(ua.match(/MicroMessenger/i)=="micromessenger") { //微信内置浏览器
dom.addEventListener('touchstart', function (event) {
},false);
}else{
if(isiOS){
dom.addEventListener('touchstart', function (event) {
//跳转到ios下载地址(示例:微信app)
window.location.href='itms-apps://itunes.apple.com/app/id414478124';
},false);
}
else if(isAndroid){
dom.addEventListener('touchstart', function (event) {
window.location.href='http://www.XXX.com/apk/demo.apk';
},false);
}else{ //PC 端
dom.addEventListener('click',function(){
//跳转到andriod下载地址
window.location.href='http://www.XXX.com/apk/demo.apk';
},false);
}
}
})();
pdf.js官网基本代码demo笔记
// atob() is used to convert base64 encoded PDF to binary-like data. // (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/ // Base64_encoding_and_decoding.) var pdfData = atob( 'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' + 'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' + 'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' + 'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' + 'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' + 'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' + 'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' + 'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' + 'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' + 'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' + 'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' + 'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' + 'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G'); // Loaded via <script> tag, create shortcut to access PDF.js exports. var pdfjsLib = window['pdfjs-dist/build/pdf']; // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js'; // Using DocumentInitParameters object to load binary data. var loadingTask = pdfjsLib.getDocument({data: pdfData}); loadingTask.promise.then(function(pdf) { console.log('PDF loaded'); // Fetch the first page var pageNumber = 1; pdf.getPage(pageNumber).then(function(page) { console.log('Page loaded'); var scale = 1.5; var viewport = page.getViewport(scale); // Prepare canvas using PDF page dimensions var canvas = document.getElementById('the-canvas'); var context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context var renderContext = { canvasContext: context, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.then(function () { console.log('Page rendered'); }); }); }, function (reason) { // PDF loading error console.error(reason); });
判断移动端、ipad设备
try { if(/Android|Windows Phone|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { window.location.href = "https://pc.com/"; } else if(/iPad/i.test(navigator.userAgent)) { window.location.href = "https://pad.com/" } } catch(e) {}