云顶娱乐棋牌-云顶娱乐每天送6元
做最好的网站

file文件选取表单元素二三事,前端当三步跳件操

indexedDB 基本采纳

2017/12/14 · 基础本领 · 1 评论 · file文件选取表单元素二三事,前端当三步跳件操作与上传云顶娱乐棋牌:。IndexedDB

原稿出处: 党黎明   


indexedDB简介:

indexedDB 是一种采纳浏览器存款和储蓄大量数目标方法.它创制的多少能够被询问,况兼能够离线使用.

云顶娱乐棋牌, 

indexedDB 有以下特点:

  1. indexedDBWebSQL 数据库的替代品
  2. indexedDB规行矩步同源协议(只好采访同域中存款和储蓄的多寡,而无法访谈别的域的)
  3. API包含异步API同步API二种:繁多气象下利用异步API; 同步API必须同 WebWorkers 一起使用, 最近尚未浏览器协理同步API
  4. indexedDB 是职业格局的数据库, 使用 key-value 键值对积存数据
  5. indexedDB 不行使结构化查询语言(SQL). 它通过索引(index)所发出的指针(cursor)来成功查询操作

HTML input type=file文件选拔表单成分二三事

2015/11/24 · HTML5 · 文件

原来的文章出处: 张鑫旭   

前者当和姑件操作与上传

2017/12/07 · JavaScript · 1 评论 · 文件

初稿出处: 人人网FED博客   

前者不能像原生APP同样直接操作当三步跳件,不然的话张开个网页就能够把客户计算机上的文书偷光了,所以须要通过客户触发,客商可透过以下三种方式操作触发:

  1. 透过input type=”file” 选取地面文件
  2. 经过拖拽的诀窍把公文拖过来
  3. 在编辑框里面复制粘贴

第一种是最常用的花招,日常还有或然会自定义三个开关,然后盖在它上面,因为type=”file”的input倒霉改造样式。如下代码写贰个精选控件,并放在form里面:

JavaScript

<form> <input type="file" id="file-input" name="fileContent"> </form>

1
2
3
<form>
    <input type="file" id="file-input" name="fileContent">
</form>

下一场就足以用FormData得到整个表单的内容:

把input的value和formData打字与印刷出来是这么的:

云顶娱乐每天送6元 1

能够看出文件的路子是三个假的不二等秘书技,也正是说在浏览器不可能获得到文件的实际贮存地方。相同的时候FormData打字与印刷出来是三个空的Objet,但并不是说它的故事情节是空的,只是它对前端开拓职员是晶莹剔透的,不可能查看、修改、删除里面的内容,只可以append增多字段。

FormData不可能获取文件的剧情,而使用FileReader能够读取整个文件的原委。客商选用文件从此,input.files就能够赢得顾客选中的文件,如下代码:

JavaScript

$("#file-input").on("change", function() { let fileReader = new FileReader(), fileType = this.files[0].type; fileReader.onload = function() { if (/^image/.test(fileType)) { // 读取结果在file里德r.result里面 $(`<img src="${this.result}">`).appendTo("body"); } } // 打字与印刷原始File对象 console.log(this.files[0]); // base64格局读取 fileReader.readAsDataUEnclaveL(this.files[0]); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$("#file-input").on("change", function() {
    let fileReader = new FileReader(),
        fileType = this.files[0].type;
    fileReader.onload = function() {
        if (/^image/.test(fileType)) {
            // 读取结果在fileReader.result里面
            $(`<img src="${this.result}">`).appendTo("body");
        }
    }
    // 打印原始File对象
    console.log(this.files[0]);
    // base64方式读取
    fileReader.readAsDataURL(this.files[0]);    
});

把本来的File对象打字与印刷出来是这么的:

云顶娱乐每天送6元 2

它是贰个window.File的实例,富含了文件的修改时间、文件名、文件的轻重、文件的mime类型等。假设须求限制上传文件的高低就可以经过判定size属性有没有超,单位是字节,而要决断是或不是为图片文件就能够透过type类型是还是不是以image开首。通过判定文件名的后缀或者会防止,而通过这种判定会相比准。上边的代码应用了叁个正则决断,假诺是一张图片的话就把它赋值给img的src,并增多到dom里面,但实际这段代码有一点难题,便是web不是富有的图形都能通过img标签显示出来,平时是jpg/png/gif这两种,所以你应当须求再剖断一下图片格式,如能够把推断改成:

JavaScript

/^image/[jpeg|png|gif]/.test(this.type)

1
/^image/[jpeg|png|gif]/.test(this.type)

然后实例化多个FileReader,调它的readAsDataU奥德赛L并把File对象传给它,监听它的onload事件,load完读取的结果就在它的result属性里了。它是叁个base64格式的,可一贯赋值给一个img的src.

选用FileReader除了可读取为base64之外,还能够读取为以下格式:

JavaScript

fileReader.readAsDataURL(this.files[0]); // 以二进制字符串格局读取,结果是二进制内容的utf-8格局,已被丢弃了 fileReader.readAsBinaryString(this.files[0]); // 以原始二进制形式读取,读取结果可一贯转成整数数组 fileReader.readAsArrayBuffer(this.files[0]);

1
2
3
4
5
6
7
fileReader.readAsDataURL(this.files[0]);
// 以二进制字符串方式读取,结果是二进制内容的utf-8形式,已被废弃了
fileReader.readAsBinaryString(this.files[0]);
// 以原始二进制方式读取,读取结果可直接转成整数数组
fileReader.readAsArrayBuffer(this.files[0]);

别的的机借使能读取为ArrayBuffer,它是贰个本来二进制格式的结果。把ArrayBuffer打字与印刷出来是这么的:

云顶娱乐每天送6元 3

能够看来,它对前端开拓人士也是晶莹剔透的,不可能间接读取里面包车型客车内容,但足以由此ArrayBuffer.length获得长度,还是可以够转成整型数组,就能够明了文书的原始二进制内容了:

JavaScript

let buffer = this.result; // 依次每字节8位读取,放到多少个子弹头数组 let view = new Uint8Array(buffer); console.log(view);

1
2
3
4
let buffer = this.result;
// 依次每字节8位读取,放到一个整数数组
let view = new Uint8Array(buffer);
console.log(view);

就算是由此第三种拖拽的措施,应该怎么读取文件呢?如下html(样式略):

JavaScript

<div class="img-container"> drop your image here </div>

1
2
3
<div class="img-container">
    drop your image here
</div>

那将要页面突显二个框:

云顶娱乐每天送6元 4

下一场监听它的拖拽事件:

JavaScript

$(".img-container").on("dragover", function (event) { event.preventDefault(); }) .on("drop", function(event) { event.preventDefault(); // 数据在event的dataTransfer对象里 let file = event.originalEvent.dataTransfer.files[0]; // 然后就能够运用FileReader进行操作 fileReader.readAsDataU奥迪Q5L(file); // 也许是丰盛到二个FormData let formData = new FormData(); formData.append("fileContent", file); })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(".img-container").on("dragover", function (event) {
    event.preventDefault();
})
 
.on("drop", function(event) {
    event.preventDefault();
    // 数据在event的dataTransfer对象里
    let file = event.originalEvent.dataTransfer.files[0];
 
    // 然后就可以使用FileReader进行操作
    fileReader.readAsDataURL(file);
 
    // 或者是添加到一个FormData
    let formData = new FormData();
    formData.append("fileContent", file);
})

数据在drop事件的event.dataTransfer.files里面,得到这几个File对象之后即可和输入框实行同样的操作了,即接纳File里德r读取,大概是新建八个空的formData,然后把它append到formData里面。

第三种粘贴的不二等秘书籍,经常是在二个编写制定框里操作,如把div的contenteditable设置为true:

JavaScript

<div contenteditable="true"> hello, paste your image here </div>

1
2
3
<div contenteditable="true">
      hello, paste your image here
</div>

粘贴的数额是在event.clipboardData.files里面:

JavaScript

$("#editor").on("paste", function(event) { let file = event.originalEvent.clipboardData.files[0]; });

1
2
3
$("#editor").on("paste", function(event) {
    let file = event.originalEvent.clipboardData.files[0];
});

而是Safari的粘合不是透过event传递的,它是直接在输入框里面增多一张图纸,如下图所示:

云顶娱乐每天送6元 5

它新建了三个img标签,并把img的src指向三个blob的本地数据。什么是blob呢,如何读取blob的内容吗?

blob是一类别公事的囤积格式,它能够积存大致任何格式的从头到尾的经过,如json:

JavaScript

let data = {hello: "world"}; let blob = new Blob([JSON.stringify(data)], {type : 'application/json'});

1
2
3
let data = {hello: "world"};
let blob = new Blob([JSON.stringify(data)],
  {type : 'application/json'});

为了获得本地的blob数据,大家得以用ajax发个地点的央浼:

JavaScript

$("#editor").on("paste", function(event) { // 必要setTimeout 0等图片出来了再管理 setTimeout(() => { let img = $(this).find("img[src^='blob']")[0]; console.log(img.src); // 用二个xhr获取blob数据 let xhr = new XMLHttpRequest(); xhr.open("GET", img.src); // 改动mime类型 xhr.responseType = "blob"; xhr.onload = function () { // response就是三个Blob对象 console.log(this.response); }; xhr.send(); }, 0); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$("#editor").on("paste", function(event) {
    // 需要setTimeout 0等图片出来了再处理
    setTimeout(() => {
        let img = $(this).find("img[src^='blob']")[0];
        console.log(img.src);
        // 用一个xhr获取blob数据
        let xhr = new XMLHttpRequest();
        xhr.open("GET", img.src);
        // 改变mime类型
        xhr.responseType = "blob";
        xhr.onload = function () {
            // response就是一个Blob对象
            console.log(this.response);
        };
        xhr.send();
    }, 0);
});

地点代码把blob打字与印刷出来是那般的:

云顶娱乐每天送6元 6

能收获它的大大小小和类型,不过具体内容也是不可知的,它有三个slice的法子,可用以切割大文件。和File同样,能够应用FileReader读取它的内容:

JavaScript

function readBlob(blobImg) { let fileReader = new FileReader(); fileReader.onload = function() { console.log(this.result); } fileReader.onerror = function(err) { console.log(err); } fileReader.readAsDataURL(blobImg); } readBlob(this.response);

1
2
3
4
5
6
7
8
9
10
11
12
function readBlob(blobImg) {
    let fileReader = new FileReader();
    fileReader.onload = function() {
        console.log(this.result);
    }
    fileReader.onerror = function(err) {
        console.log(err);
    }
    fileReader.readAsDataURL(blobImg);
}
 
readBlob(this.response);

除此,还是能利用window.U福睿斯L读取,那是贰个新的API,平时和ServiceWorker配套使用,因为SW里面平时要深入分析url。如下代码:

JavaScript

function readBlob(blobImg) { let urlCreator = window.URL || window.webkitURL; // 得到base64结果 let imageUrl = urlCreator.createObjectURL(this.response); return imageUrl; } readBlob(this.response);

1
2
3
4
5
6
7
8
function readBlob(blobImg) {
    let urlCreator = window.URL || window.webkitURL;
    // 得到base64结果
    let imageUrl = urlCreator.createObjectURL(this.response);
    return imageUrl;
}
 
readBlob(this.response);

关于src使用的是blob链接的,除了上边提到的img之外,其他二个很布满的是video标签,如youtobe的摄像正是采取的blob:

云顶娱乐每天送6元 7

这种数量不是直接在本地的,而是通过不停伏乞录像数据,然后再经过blob那个容器媒介增多到video里面,它也是通过URubiconL的API创制的:

JavaScript

let mediaSource = new MediaSource(); video.src = URL.createObjectURL(mediaSource); let sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'); sourceBuffer.appendBuffer(buf);

1
2
3
4
let mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
let sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
sourceBuffer.appendBuffer(buf);

实际我也没推行过,不再张开探究。

云顶娱乐每天送6元,上边,大家使用了两种格局获取文件内容,最后获得:

  1. FormData格式
  2. FileReader读获得到的base64可能ArrayBuffer二进制格式

尽管平素正是三个FormData了,那么间接用ajax发出去就行了,不用做任什么地点理:

JavaScript

let form = document.querySelector("form"), formData = new FormData(form), formData.append("fileName", "photo.png"); let xhr = new XMLHttpRequest(); // 如果上传文件的接口叫upload xhr.open("POST", "/upload"); xhr.send(formData);

1
2
3
4
5
6
7
8
let form = document.querySelector("form"),
    formData = new FormData(form),
formData.append("fileName", "photo.png");
 
let xhr = new XMLHttpRequest();
// 假设上传文件的接口叫upload
xhr.open("POST", "/upload");
xhr.send(formData);

假若用jQuery的话,要安装四个本性为false:

JavaScript

$.ajax({ url: "/upload", type: "POST", data: formData, processData: false, // 不管理多少 contentType: false // 不设置剧情类型 });

1
2
3
4
5
6
7
$.ajax({
    url: "/upload",
    type: "POST",
    data: formData,
    processData: false,  // 不处理数据
    contentType: false   // 不设置内容类型
});

因为jQuery会自动把内容做一些转义,而且依据data自动安装须求mime类型,这里告诉jQuery直接用xhr.send发出去就行了。

重点调整台发央求的数量:

云顶娱乐每天送6元 8

能够看见那是一种有别于于用&连接参数的形式,它的编码格式是multipart/form-data,正是上传文件form表单写的enctype:

JavaScript

<form enctype="multipart/form-data" method="post"> <input type="file" name="fileContent"> </form>

1
2
3
<form enctype="multipart/form-data" method="post">
    <input type="file" name="fileContent">
</form>

一旦xhr.send的是FormData类型话,它会自行设置enctype,倘若您用暗中认可表单提交上传文件的话就得在form上边安装那个性格,因为上传文件只可以使用POST的这种编码。常用的POST编码是application/x-www-form-urlencoded,它和GET同样,发送的数量里面,参数和参数之间接选举取&连接,如:

key1=value1&key2=value2

特殊字符做转义,这一个数量POST是献身乞请body里的,而GET是拼在url下面的,若是用jq的话,jq会帮你拼并做转义。

而上传文件用的这种multipart/form-data,参数和参数之间是且一个一样的字符串隔离的,上边的是选择:

——WebKitFormBoundary72yvM25iSPYZ4a3F

以此字符经常会博得比较长、相当的轻便,因为要力保符合规律的内容之中不会产出那一个字符串,那样内容的特殊字符就不用做转义了。

央求的contentType被浏览器设置成:

Content-Type:

multipart/form-data; boundary=—-WebKitFormBoundary72yvM25iSPYZ4a3F

后端服务通过那些就掌握怎么解析那样一段数据了。(平常是选拔的框架管理了,而现实的接口不必要关心应该怎么分析)

假如读取结果是ArrayBuffer的话,也是足以直接用xhr.send发送出去的,但是通常我们不会一直把贰个文书的内容发出去,而是用有些字段名等于文件内容的点子。假如您读取为ArrayBuffer的话再上传的话实际效果不是相当的大,还比不上直接用formData增添一个File对象的故事情节,因为地点三种方式都足以拿到File对象。假诺一齐始正是一个ArrayBuffer了,那么能够转成blob然后再append到FormData里面。

运用相当多的应该是base64,因为前面多少个常常要管理图片,读取为base64之后就能够把它画到多少个canvas里面,然后就可以做一些管理,如压缩、裁剪、旋转等。最终再用canvas导出三个base64格式的图形,那怎么上传base64格式的呢?

率先种是拼两个表单上传的multipart/form-data的格式,再用xhr.sendAsBinary发出去,如下代码:

JavaScript

let boundary = "----------boundaryasoifvlkasldvavoadv"; xhr.sendAsBinary([ // name=data boundary, 'Content-Disposition: form-data; name="data"; filename="' + fileName + '"', 'Content-Type: ' + "image/" + fileType, '', atob(base64Data), boundary, //name=imageType boundary, 'Content-Disposition: form-data; name="imageType"', '', fileType, boundary + '--' ].join('rn'));

1
2
3
4
5
6
7
8
9
10
11
12
13
let boundary = "----------boundaryasoifvlkasldvavoadv";
xhr.sendAsBinary([
    // name=data
    boundary,
        'Content-Disposition: form-data; name="data"; filename="' + fileName + '"',
        'Content-Type: ' + "image/" + fileType, '',
        atob(base64Data), boundary,
    //name=imageType
    boundary,
        'Content-Disposition: form-data; name="imageType"', '',
        fileType,
    boundary + '--'
].join('rn'));

地点代码应用了window.atob的api,它能够把base64还原成原始内容的字符串表示,如下图所示:

云顶娱乐每天送6元 9

btoa是把内容转化成base64编码,而atob是把base64还原。在调atob在此以前,须要把象征内容格式的不属于base64内容的字符串去掉,即上边代码第一行的replace管理。

如此那般就和行使formData类似了,然而由于sendAsBinary已经被deprecated了,所以新代码不提议再采纳这种艺术。那怎么做呢?

能够把base64转化成blob,然后再append到贰个formData里面,上边包车型大巴函数(来自b64-to-blob)可以把base64转成blob:

JavaScript

contentType = contentType || ''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    contentType = contentType || '';
    sliceSize = sliceSize || 512;
    var byteCharacters = atob(b64Data);
    var byteArrays = [];
    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      var slice = byteCharacters.slice(offset, offset + sliceSize);
      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      var byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
    var blob = new Blob(byteArrays, {type: contentType});
    return blob;
}

下一场就能够append到formData里面:

JavaScript

let blob = b64toBlob(b64Data, "image/png"), formData = new FormData(); formData.append("fileContent", blob);

1
2
3
let blob = b64toBlob(b64Data, "image/png"),
    formData = new FormData();
formData.append("fileContent", blob);

如此那般就绝不自个儿去拼一个multipart/form-data的格式数据了。

下面管理和上传文件的API能够配合到IE10+,假使要相称老的浏览器应当咋做吧?

可以依傍八个iframe,原理是私下认可的form表单提交会刷新页面,或然跳到target钦定的非常url,可是只要把ifrmae的target指向二个iframe,那么刷新的正是iframe,重临结果也会来得在ifame,然后拿走那一个ifrmae的内容就可拿到上传接口再次来到的结果。

如下代码:

JavaScript

iframe.display = "none"; iframe.name = "form-iframe"; document.body.appendChild(iframe); // 改造form的target form.target = "form-iframe"; iframe.onload = function() { //获取iframe的剧情,即服务重返的多少 let responseText = this.contentDocument.body.textContent || this.contentWindow.document.body.textContent; }; form.submit();

1
2
3
4
5
6
7
8
9
10
11
12
13
iframe.display = "none";
iframe.name = "form-iframe";
document.body.appendChild(iframe);
// 改变form的target
form.target = "form-iframe";
iframe.onload = function() {
    //获取iframe的内容,即服务返回的数据
    let responseText = this.contentDocument.body.textContent
            || this.contentWindow.document.body.textContent;
};
form.submit();

form.submit会触宣布单提交,当呼吁完结(成功大概失利)之后就能够触发iframe的onload事件,然后在onload事件获得再次来到的多少,假诺央浼失利了的话,iframe里的原委就为空,能够用这么些论断伏乞有未遂。

利用iframe未有艺术得到上传进程,使用xhr能够拿走当前上传的快慢,这几个是在XMLHttpRequest 2.0引进的:

JavaScript

xhr.upload.onprogress = function (event) { if (event.lengthComputable) { // 当前上传进程的百分比 duringCallback ((event.loaded / event.total)*100); } };

1
2
3
4
5
6
xhr.upload.onprogress = function (event) {
    if (event.lengthComputable) {
        // 当前上传进度的百分比
        duringCallback ((event.loaded / event.total)*100);
    }
};

如此就可以做贰个真实的loading进程条。

本文商讨了3种交互方式的读取情势,通过input控件在input.files能够获得File文件对象,通过拖拽的是在drop事件的event.dataTransfer.files里面,而经过粘贴的paste事件在event.clipboardData.files里面,Safari那一个怪胎是在编辑器里面插入二个src指向地面包车型地铁img标签,可以因而发送二个呼吁加载本地的blob数据,然后再通过FileReader读取,或许间接append到formData里面。得到的File对象就能够直接助长到FormData里面,若是急需先读取base64格式做管理的,那么能够把拍卖后的base64转化为blob数据再append到formData里面。对于老浏览器,能够应用二个iframe化解表单提交刷新页面恐怕跳页的标题。

一句话来讲,前端管理和上传当麻芋果件应当大概正是这么些内容了,可是应该还会有大多细节尚未谈起到,读者可因而本文列的矛头自行实行。假如有其余的上传格局还请告诉。

1 赞 收藏 1 评论

云顶娱乐每天送6元 10

调减HTTP诉求(大型网址优化技术)

2015/11/26 · HTML5 · HTTP

初稿出处: Kelly   

在网站开拓进程中,对于页面包车型客车加载功能日常都想尽办法求快。那么,怎么让手艺更加快吧?收缩页面乞请 是一个优化页面加载速度很好的措施。上一篇博文大家讲课了 “利用将小Logo合成一张背景图来压缩HTTP央浼”,那么,这一篇博文将教师  “ 将图片转成二进制并生成Base64编码,能够在网页中经过url查看图片”。

一、为什么接纳将图纸转成二进制并生成Base64编码,能够在网页中通过url查看图片的措施收缩HTTP央浼数?

何以小编会解说“将图片转成二进制并生成Base64编码,能够在网页中经过url查看图片” 这一种办法来压缩HTTP须要,进而优化页面吗?这里呢,是关联到运动端的Logo使用。上一篇博文所讲的章程是不是接纳于手提式有线电话机端的网页呢?

只是,它会现出三个题目:背景图+css突显图标时,Logo本身不恐怕缩放,例如背景图中64px*64px的Logo,显示到分界面时必得安装icon的深浅也是64*64。在PC网页中那日常不会有何难点,但在活动端设备上就完全不行。同样是4英寸的手提式有线话机荧屏,其分辨率有十分大希望是320*400,也可能是640*800,以致也只怕是1918*1080。这样64px*64px的Logo在分歧的配备上看起来的尺寸就能够距离特别生硬。

幸亏的是,手提式有线话机上的浏览器基本对此做了优化,会把设备模拟成更低的分辨率。比方在1136*640的IPHONE 5中收获$(window).width(),抽取来的是320实际不是640,那样三个大幅为160px的图纸占用的是荧屏宽度的贰分之一,实际不是半数。手提式有线电话机设备这么管理是为着消除宽容性难点。除了网页,包蕴手提式有线电电话机上app的界面,在retina显示器上和非retina荧屏上的深浅是完全同样的,都以因为对分辨率做了拍卖。

可是,移动道具这么的管理格局并不可能一心缓慢解决难点,因为机器的若是性猜度在非常多时候是不正好的,尤其是在android设备中。为了越来越好地操纵成分展现的轻重缓急,化解的章程就是用pt代替ps,px是对应显示器的分辨率,而pt是针对性人眼睛实在认为的尺寸,无论在何种分辨率的设施上,72pt固定是1英寸。

HTML的img标签成分的src属性不只是能够钦定url,也能够钦命图片的二进制数据流。然后经过img元素的机动缩放作用,内定img的深浅,就可以达成在不一样分辨率的设施上出示同一的Logo大小。

二、使用Base64编码收缩页面央浼数

当大家的叁个页面中要传播比非常多图纸时,非常是有的小图标,十几K、几K,以致是字节等级大小的小Logo,这个小Logo都会追加HTTP央浼,假使多了,就能够给服务器带来相当的大的压力。举例要下载一些一两K大的小Logo,其实要求时带上的额外消息有望比Logo的尺寸还要大。所以,在伸手越来越多时,在网络传输的数码自然就越来越多了,传输的数额自然也就变慢了。而这里,我们运用Base64的编码格局将图片直接嵌入到网页中,并非从外界载入,这样就裁减了HTTP需要。当然了,它有贰个小缺欠,便是使当前页面包车型大巴大大小小变大了(对于优化来讲,其实这些能够忽略,影响微乎其微)。看一下下图,小Logo大小为2.4k,等待响应时间是14ms,而接受多少,也正是下载时间约为0ms;总之,在有大批量小Logo下载的时候,那样的艺术去优化能大大进步网址的质量(在jquery mobile和Tmall的手提式无线电话机站上边都有用到此技能)。

云顶娱乐每天送6元 11

三、开辟思路

将小Logo放在以icon_发端的公文夹里(以分别不用生成base64的图形的文件夹)—>用程序去遍历文件夹图片 —>将每张图片的base64编码放在壹个js对象里—>在HTML页面包车型客车img标签里 使用品质 icon-data = ‘Logo名(不带后缀)’来体现图片 —> JS文件写三个函数对icon-data属性进行转移,调换来src属性,然后值就透过icon-data的属性值获得图标名,然后开展对应的更迭获得相应Logo的base64编码 —> 呈现图片

四、代码达成

XHTML

<?php $pathinfo = pathinfo($_SERVER['SCRIPT_FILENAME']); define('ROOT', $pathinfo['dirname']); function generateIcon_mobile() { $imgRoot = ROOT."/img/mobile"; $iterator = new DirectoryIterator($imgRoot); foreach ($iterator as $file) { if ($file->isDot()) continue; $filename = $file->getFilename(); //识别出是或不是以icon_开始的文本夹,假诺是,则对此文件夹的图标进行base64编码管理if ($file->isDir() && 0 === strncasecmp('icon_', $filename, 5)) { generateIconMobileCallback("$imgRoot/$filename", ROOT."/js/mobile"); } } } function generateIconMobileCallback($iconDir, $styleSaveDir) { //保存成js的文本名 $saveName = array_pop(explode('/', $iconDir)); //JS文件保留路线 $styleSavePath = $styleSaveDir.'/'.$saveName.'.js'; //将当前目录下的装有文件及MD5组成三个识别字符串 $fileMap = array(); $iterator = new DirectoryIterator($iconDir); foreach ($iterator as $file) { if ($file->isDot()) continue; $fileName = $file->getFilename(); if ($file->isDir()) { generateIconMobileCallback($iconDir.'/'.$fileName, $styleSaveDir.'/'.$fileName); } else { $fileMap[$fileName] = md5_file($file->getRealPath()); } } ksort($fileMap); $fileMapStr = json_encode($fileMap); //确认保证目录可写 ensure_writable_dir($styleSaveDir); //js文件句柄 $wirteHandle = fopen($styleSavePath, 'w'); //当前小Logo文件夹的相对路径$iconSaveRelative = substr($iconDir, strlen(ROOT)); //写入,开始化保存数据的对象 fwrite($wirteHandle, "/** icon in dir: $iconSaveRelative/ */ nif(typeof($iconData) == 'undefined') $iconData={};"); foreach ($fileMap as $fileName => $md5) { //当前图片的相对路径 $fullPathName = "$iconDir/$fileName"; //获得路线音信 $pathInfo = pathinfo($fullPathName); //获得文件名(未有后缀) $fileNameNoExt = $pathInfo['filename']; //获得图片消息 $imageSize = getimagesize($fullPathName); //获得文件的后缀 switch ($imageSize[2]) { case IMAGETYPE_GIF: $imageType = 'gif'; break; case IMAGETYPE_JPEG: $imageType = 'jpg'; break; case IMAGETYPE_PNG: $imageType = 'png'; break; default: $imageType = 'jpg'; break; } //获得图片财富 $readHandle = fopen($fullPathName, 'r'); //将图片转成二进制并生成Base64编码 $base64 = base64_encode(fread($readHandle, filesize($fullPathName))); //关闭财富fclose($readHandle); //将Base64编码写入js文件中 fwrite($wirteHandle, "n$iconData.$fileNameNoExt="data:image/$imageType;base64,$base64";"); } //最终换个行 fwrite($wirteHandle, "n"); //关闭能源fclose($wirteHandle); //管理成功的Logo文件夹给予提示 echo '<p>'.$iconSaveRelative. ' saved</p>'; } /** * 确认保证文件夹存在并可写 * * @param string $dir */ function ensure_writable_dir($dir) { if(!file_exists($dir)) { mkdir($dir, 0766, true); @chmod($dir, 0766); @chmod($dir, 0777); } else if(!is_writable($dir)) { @chmod($dir, 0766); @chmod($dir, 0777); if(!@is_writable($dir)) { throw new BusinessLogicException("目录不可写", $dir); } } } generateIcon_mobile(); ?> <!DOCTYPE html> <html> <head> <title></title> </head> <body> <br> <br> <br> <div>我们直接引进所生成的js文件,测量试验一下是或不是中标</div> <br> <div>直接在img标签里步向 icon-data = 'Logo文件名' 比方<img icon-data="tryit">,查看效果</div> <br> <br> <br> <img icon-data="tryit"> <script src="js/mobile/icon_pink.js"></script> <script src="js/mobile/jquery.all.min.js"></script> <script src="js/mobile/attrHandle.js"></script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
    $pathinfo = pathinfo($_SERVER['SCRIPT_FILENAME']);
    define('ROOT', $pathinfo['dirname']);
 
    function generateIcon_mobile() {
        $imgRoot = ROOT."/img/mobile";
        $iterator = new DirectoryIterator($imgRoot);
        foreach ($iterator as $file) {
            if ($file->isDot()) continue;
            $filename = $file->getFilename();
 
            //识别出是否以icon_开头的文件夹,如果是,则对此文件夹的图标进行base64编码处理
            if ($file->isDir() && 0 === strncasecmp('icon_', $filename, 5)) {
                generateIconMobileCallback("$imgRoot/$filename", ROOT."/js/mobile");
            }
        }
 
    }
 
    function generateIconMobileCallback($iconDir, $styleSaveDir) {
        //保存成js的文件名
        $saveName = array_pop(explode('/', $iconDir));
        //JS文件保存路径
        $styleSavePath = $styleSaveDir.'/'.$saveName.'.js';
 
        //将当前目录下的所有文件及MD5组成一个识别字符串
        $fileMap = array();
        $iterator = new DirectoryIterator($iconDir);
        foreach ($iterator as $file) {
            if ($file->isDot()) continue;
            $fileName = $file->getFilename();
            if ($file->isDir()) {
                generateIconMobileCallback($iconDir.'/'.$fileName, $styleSaveDir.'/'.$fileName);
            } else {
                $fileMap[$fileName] = md5_file($file->getRealPath());
            }
        }
        ksort($fileMap);
        $fileMapStr = json_encode($fileMap);
 
        //确保目录可写
        ensure_writable_dir($styleSaveDir);
 
        //js文件句柄
        $wirteHandle = fopen($styleSavePath, 'w');
        //当前小图标文件夹的相对路径
        $iconSaveRelative = substr($iconDir, strlen(ROOT));
        //写入,初始化保存数据的对象
        fwrite($wirteHandle, "/** icon in dir: $iconSaveRelative/ */ nif(typeof($iconData) == 'undefined') $iconData={};");
        foreach ($fileMap as $fileName => $md5) {
            //当前图片的绝对路径
            $fullPathName = "$iconDir/$fileName";
            //取得路径信息
            $pathInfo = pathinfo($fullPathName);
            //取得文件名(没有后缀)
            $fileNameNoExt = $pathInfo['filename'];
            //取得图片信息
            $imageSize = getimagesize($fullPathName);
 
            //取得文件的后缀
            switch ($imageSize[2]) {
                case IMAGETYPE_GIF:
                    $imageType = 'gif';
                    break;
                case IMAGETYPE_JPEG:
                    $imageType = 'jpg';
                    break;
                case IMAGETYPE_PNG:
                    $imageType = 'png';
                    break;
 
                default:
                    $imageType = 'jpg';
                    break;
            }
 
            //取得图片资源
            $readHandle = fopen($fullPathName, 'r');
            //将图片转成二进制并生成Base64编码
            $base64 = base64_encode(fread($readHandle, filesize($fullPathName)));
            //关闭资源
            fclose($readHandle);
            //将Base64编码写入js文件中
            fwrite($wirteHandle, "n$iconData.$fileNameNoExt="data:image/$imageType;base64,$base64";");
        }
        //最后换个行
        fwrite($wirteHandle, "n");
        //关闭资源
        fclose($wirteHandle);
 
        //处理成功的图标文件夹给予提示
        echo '<p>'.$iconSaveRelative. ' saved</p>';  
    }
 
    /**
    * 确保文件夹存在并可写
    *
    * @param string $dir
    */
    function ensure_writable_dir($dir) {
        if(!file_exists($dir)) {
            mkdir($dir, 0766, true);
            @chmod($dir, 0766);
            @chmod($dir, 0777);
        }
        else if(!is_writable($dir)) {
            @chmod($dir, 0766);
            @chmod($dir, 0777);
            if(!@is_writable($dir)) {
                throw new BusinessLogicException("目录不可写", $dir);
            }
        }
    }
    generateIcon_mobile();
?>
 
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<br>
<br>
<br>
 
<div>我们直接引入所生成的js文件,测试一下是否成功</div>
<br>
<div>直接在img标签里加入 icon-data = '图标文件名'  例如  <img icon-data="tryit">,查看效果</div>
<br>
<br>
<br>
    <img icon-data="tryit">
    <script src="js/mobile/icon_pink.js"></script>
    <script src="js/mobile/jquery.all.min.js"></script>
    <script src="js/mobile/attrHandle.js"></script>
</body>
</html>

接下来这里附上属性转变的JS代码

JavaScript

$(function(){ setIconData(); }); function setIconData() { if (typeof($iconData != 'undefined')) { $('img[icon-data]').each(function() { var self = $(this); var name = self.attr('icon-data'); if (typeof($iconData[name]) != 'undefined') { self.attr('src', $iconData[name]); self.removeAttr('icon-data'); } }); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function(){
    setIconData();
});
 
function setIconData() {
    if (typeof($iconData != 'undefined')) {
        $('img[icon-data]').each(function() {
            var self = $(this);
            var name = self.attr('icon-data');
            if (typeof($iconData[name]) != 'undefined') {
                self.attr('src', $iconData[name]);
                self.removeAttr('icon-data');
            }
        });
    }
}

 

五、实现效果与利益

  那是页面输入效果,小Logo正常呈现出来了

 

云顶娱乐每天送6元 12

 

此处大家自动生成的JS文件是那样子的格式:

云顶娱乐每天送6元 13

 

页面调用的代码:

云顶娱乐每天送6元 14

 

JS对img的icon-data属性调换处理的代码:

云顶娱乐每天送6元 15

 

我们比较下用base64编码和毫无base64时所开销的岁月:

先看不用的快慢

云顶娱乐每天送6元 16

再看大家用了base64编码的速度   云顶娱乐每天送6元 17

 

设若一个页面有不菲小Logo,那么这种方式对网址的性质优化会有大大的进步。最近此种优化方案是用在自己前日的系列中移动端,而上一篇博文疏解的变化背景图的优化方案用在大家项目中的PC端。优化功能是很明显的!当然了,base64编码这种格局也能够用在PC端,大家的门类怎么将它用在手机端,本博文开首部分也会有对其做解释。这里测量试验自身就直接在PC端测量检验,手提式有线电话机端测量检验也是叁个样的。

此地本身补偿有些:

(1)所生成的base64的js文件是在支付中就成形的了,并不是在客户访谈时才去变通,笔者把HTML代码和PHP代码写在多个文件里是方便人民群众,在实际项目中是分开的;

(2)使用此种优化才能有它的助益,当然也是有它的后天不足,独有切合本身项指标优化才干才是好手艺;

(3)个中优化技能建议使用在手提式有线电话机端(可以消除背景图优化措施所不能够一下子就解决了的标题),而PC端的则用统一小Logo生成背景图的方法(看此文:);

(4)此种优化技术平日用于小Logo(十几K以下),也正是HTTP响应时间远远当先下载时间的时候,用此措施优化寻访到显明的功效;

(5)当然能够合作别的优化本事联合行使,效果更鲜明,举个例子缓存等。

 

那三回就享受那么多给大家,代码小编都贴上了,何况多数都标上了讲授,方便大家领略。

即便此博文中有哪里讲得令人难以理解,迎接留言沟通,若有疏解错的地点迎接建议。

一旦您感到你能在此博理学到了新知识,请为自己顶一个,如小说中有表达错的地方,应接提出。

  相互学习,共同提升!

2 赞 2 收藏 评论

云顶娱乐每天送6元 18

一分钟预览 HTTP2 本性和抓包解析

2016/09/26 · JavaScript · HTTP/2

原稿出处: 段隆贤   

一、使用indexedDB的基本情势

  1. 打开数据库何况初步一个事务。
  2. 创设多少个 objecStore
  3. 打造一个呼吁来施行一些数据库操作,像增加或提取数额等。
  4. 透过监听正确类型的 DOM 事件以伺机操作实现。
  5. 在操作结果上实行部分操作(能够在 request 对象中找到)

一、良生- input type=file与公事上传

正文所说的input type=file指的是type类型是fileinput要素,最简HTML代码如下:

XHTML

<input type=file>

1
<input type=file>

而是,为了习贯,大家多写成:

XHTML

<input type="file">

1
<input type="file">

在HTML5涌出在此之前(XHTML),大家的密封法则则某些出入:

XHTML

<input type="file" />

1
<input type="file" />

望文生义,选用文件,并上传文件。

在罪恶的旧时期,HTML5还从未出现在此之前,原生的file input表单元素只可以让大家壹次上传一张图片。不可能满足贰回上传多图的彼此须求,所以,非常多气象,就被swfupload.js给代表了,有一点逐年脱离大家视界的痛感。

然,技巧进步,如日中天,三十年河东,三十年河西。随着原生HTML5表单对多图(multiple质量)、上传前预览,二进制上传等扶助特别常见,原生的file input表单成分又迎来了新的进级,flash为背景的swfupload.js注定要落寞。

只是,对于PC项目,IE8-IE9浏览器依旧不可以小视的。所以,以后,非常流行的一种管理格局,就是HTML5 file上传和flash swfupload上传一齐组成的形式,优先选用原生HTML5上传,不帮衬的,使用flash上传。笔者前边有篇关于HTML5上传的篇章,每一日访问量极高的:“典故HTML5的可预览多图片Ajax上传”,大家有意思味能够看看。

背景

近期,http网络哀告量日益增加,以下是httparchive总括,从2011-11-01到二〇一五-09-01的乞请数量和传导大小的势头图:

云顶娱乐每天送6元 19

 

日前抢先十分之五份顾客端&服务端架构的应用程序,都是用http/1.1一而再的,今世浏览器与单个域最都林接数,都在4-6个左右,由上海体育场所Total Requests数据,借使不用CDN分流,平均有十多个左右的串行央求。
HTTP2 是一九九七年发表http1.1后的一回首要的考订,在协调层面改正了上述难点,收缩能源占用,来,直接感受一下差别:

HTTP/2 is the future of the Web, and it is here!
那是 Akamai 集团创立的贰个法定的身体力行,用以注明 HTTP/2 比较于事先的 HTTP/1.1 在性质上的宏大提高。 同期呼吁 379 张图纸,从Load time 的对照可以见到 HTTP/2 在速度上的优势。

云顶娱乐每天送6元 20

 

正文全数源码和抓包文件在github

二、创造、展开数据库

indexedDB 存在于全局对象window上, 它最要害的一个方法就是open主意, 该方法接收五个参数:

  • dbName // 数据库名称 [string]
  • version // 数据库版本 [整型number]

var DB_NAME = 'indexedDB-test', VERSION = 1, db; var request = indexedDB.open(DB_NAME, VEENCORESION); request.onsuccess = function(event) { db = event.target.result; // console.log(event.target === request); // true db.onsuccess = function(event) { console.log('数据库操作成功!'); }; db.onerror = function(event) { console.error('数据库操作产生错误!', event.target.errorCode); }; console.log('展开数据库成功!'); }; request.onerror = function(event) { console.error('创设数据库出错'); console.error('error code:', event.target.errorCode); }; request.onupgradeneeded = function(event) { // 更新目的存储空间和目录 .... };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var DB_NAME = 'indexedDB-test', VERSION = 1, db;
var request = indexedDB.open(DB_NAME, VERSION);
request.onsuccess = function(event) {
    db = event.target.result;
    // console.log(event.target === request); // true
    db.onsuccess = function(event) {
        console.log('数据库操作成功!');
    };
    db.onerror = function(event) {
        console.error('数据库操作发生错误!', event.target.errorCode);
    };
    console.log('打开数据库成功!');
};
request.onerror = function(event) {
    console.error('创建数据库出错');
    console.error('error code:', event.target.errorCode);
};
request.onupgradeneeded = function(event) {
   // 更新对象存储空间和索引 ....
};

倘诺本域下子虚乌有名叫DB_NAME的数据库,则上述代码会创立三个名叫DB_NAME、版本号为VERSION的数据库; 触发的平地风波依次为: upgradeneededsuccess.

假如已存在名称叫DB_NAME的数据库, 则上述代码会展开该数据库; 只触及success/error事件,不会触发upgradeneeded事件. db是对该数据库的引用.

二、莲安-原生input上传与表单form成分

一经想使用浏览器原生个性实现文件上传(如图片)效果,父级的form要素有个东西无法丢,正是:

XHTML

enctype="multipart/form-data"

1
enctype="multipart/form-data"

enctype属性规定在发送到服务器在此以前应当如何对表单数据开展编码,暗中同意的编码是:”application/x-www-form-urlencoded“。对于普通数据是挺适用的,可是,对于文本,科科,就不能够乱编码了,该如何就是什么样,只可以采纳multipart/form-data作为enctype属性值。

不管旧时期的单图上传,依然HTML5中的多图上传,均是这么。

HTTP/2 源自 SPDY/2

SPDY 体系左券由Google开垦,于 二〇〇九 年公开。它的宏图目的是下降 四分之二的页面加载时间。当下无数名牌的互连网公司都在大团结的网址或 应用软件 中选用了 SPDY 体系契约(当前前卫版本是 SPDY/3.1),因为它对品质的晋级是肯定的。主流的浏览器(Google、火狐、Opera)也都早就经支撑 SPDY,它早就改为了工业标准,HTTP Working-Group 最后决定以 SPDY/2 为根基,开拓 HTTP/2。HTTP/2规范于二〇一六年1月以宝马X3FC 7540业内部刊物出。

然则,HTTP/2 跟 SPDY 仍有不相同的地方,主假若以下两点:

HTTP/2 支持明文 HTTP 传输,而 SPDY 强制行使 HTTPS
HTTP/2 音讯头的压缩算法选拔 HPACK ,而非 SPDY 采取的 DEFLATE(感激网络朋友 逸风之狐指正)

左券文书档案请见:rfc7540:HTTP2

三、成立对象存款和储蓄空间和目录

在关系型数据库(如mysql)中,二个数据库中会有多张表,每张表有各自的主键、索引等;

key-value型数据库(如indexedDB)中, 三个数据库会有多个指标存款和储蓄空间,每个存款和储蓄空间有温馨的主键、索引等;

创制对象存款和储蓄空间的操作平日位于成立数据库成功回调里:

request.onupgradeneeded = function(event) { // 更新指标存储空间和目录 .... var database = event.target.result; var objectStore = database.createObjectStore("movies", { keyPath: "id" }); objectStore.createIndex('alt', 'alt', { unique: true }); objectStore.createIndex('title', 'title', { unique: false }); };

1
2
3
4
5
6
request.onupgradeneeded = function(event) { // 更新对象存储空间和索引 ....
    var database = event.target.result;
    var objectStore = database.createObjectStore("movies", { keyPath: "id" });
    objectStore.createIndex('alt', 'alt', { unique: true });
    objectStore.createIndex('title', 'title', { unique: false });
};

云顶娱乐每天送6元 21

onupgradeneeded 是我们独一能够修改数据库结构的地方。在这里面,大家得以创立和删除对象存款和储蓄空间以及创设和删除索引。

在数据库对象database上,有以下格局可供调用:

  1. createObjectStore(storeName, configObj) 创造一个目的存款和储蓄空间
    • storeName // 对象存储空间的名称 [string]
    • configObj // 该指标存款和储蓄空间的配置 [object] (个中的keyPath属性值,标识对象的该属性值独一)
  2. createIndex(indexName, objAttr, configObj) 创设一个目录
    • indexName // 索引名称 [string]
    • objAttr // 对象的本性名 [string]
    • configObj // 该索引的布局对象 [object]

三、沿见-原生file input图片上传前预览与Ajax上传

文件,越发图片,进场前能够预览,是很棒的交互体验。不走服务器,不开销流量,多棒!

非凡虽好,实现起来……

在HTML5还没出现的旧时代,唯有低版本的IE浏览器貌似有措施,使用个人的滤镜,超过安全的限定(其实是采纳了倒霉的东西),实现图片直接预览;不过呢,今年,Chrome, FireFox未有这一出,于是,想要使用原生file input实现图片的上传前预览,宽容性坎很难跨过去。

不过,后来,HTML5来了,大家出现了关键,IE10+以及其余当代浏览器,能够让大家平素读取图片的多寡,然后在页面上表现,达成了上传前预览;加上此前老IE的滤镜攻略,貌似,可行。可是呢然则,老的IE浏览器只可以最多二遍选取二个文本,由此,唯有单图上传的时候,我们能够设想思索。

思想的form提交,是要更动页面流的,也正是刷新后跳转。好的体会应该是走Ajax交互的。HTML5里面援助二进制formData数据提交,因而,能够从容Ajax提交上传的文件数量;那老旧的IE浏览器如何做?

诚如方法如下:

  1. form成分新增添target质量,其值指向页面内掩饰的贰个<iframe>元素的id, 如下暗意:
XHTML

&lt;form action="" method="post" enctype="multipart/form-data"
target="uploadIframe"&gt;&lt; &lt;iframe
id="uploadIframe"&gt;&lt;/iframe&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b5706113164219721-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b5706113164219721-2">
2
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b5706113164219721-1" class="crayon-line">
&lt;form action=&quot;&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot; target=&quot;uploadIframe&quot;&gt;&lt;
</div>
<div id="crayon-5b8f4b5706113164219721-2" class="crayon-line crayon-striped-line">
&lt;iframe id=&quot;uploadIframe&quot;&gt;&lt;/iframe&gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 处理<iframe>元素的onload事件,得到再次来到内容(如下代码暗指),具体细节非本文重视,不表。
XHTML

var doc = iframe.contentDocument ? iframe.contentDocument :
frames[iframe.id].document; var response = doc.body &&
doc.body.innerHTML;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b5706117611584350-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b5706117611584350-2">
2
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b5706117611584350-1" class="crayon-line">
var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
</div>
<div id="crayon-5b8f4b5706117611584350-2" class="crayon-line crayon-striped-line">
var response = doc.body &amp;&amp; doc.body.innerHTML;
</div>
</div></td>
</tr>
</tbody>
</table>

OK, 当然,你也足以不用像上边这么辛劳,直接运用jquery.form.js. 原理呢,就是上面那样,不过,不需求这么费劲。

HTTP2天性大概浏览

本文由云顶娱乐棋牌发布于云顶娱乐棋牌,转载请注明出处:file文件选取表单元素二三事,前端当三步跳件操

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。