zhangxinxu / quiz

小测答题收集区
536 stars 43 forks source link

JS基础测试36期 #38

Open zhangxinxu opened 5 years ago

zhangxinxu commented 5 years ago

本期小测源自Ajax多文件上传这个实际需求,内容如下:

答题前不要看别人回答,答题后可以,但不能修改自己回答

大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。

```js
// 你的JS代码写在这里
 ```

其它:

  1. 首位答题者可获得直播翻牌机会;
  2. 本次答疑直播为8月17日上午10:00,大约30分钟;
XboxYan commented 5 years ago

1.

var xhr = new XMLHttpRequest();
var target = xhr.upload;
//进度
target.onprogress = function(ev){
    console.log(ev);
}
//成功
target.onload = function(){
    console.log('success');
}
//失败
target.onerror = function(){
    console.log('fail');
}
xhr.open("POST",'/upload',true);
xhr.send(file);

2.

const filterFiles = [...files].filter((el)=>{
    return el.size<=1024*1024;//1M
})

3.

const promise = function(file){
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        var target = xhr.upload;
        target.onloadend = function(){
            //console.log('complete');
            resolve();
        }
        target.onerror = function(){
            //fail
            reject();
        }
        xhr.open("POST",'/upload',true);
        xhr.send(file);
    });
}

const promises = [...files].map(function(file){
    return promise(file);
})

Promise.all(promises).then(function(values) {
    //console.log('all complete');
});
Despair-lj commented 5 years ago
// 1
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(event) {
  if (event.lengthComputable) {
    console.log(`上传进度为: ${event.loaded} of ${event.total} bytes`);
  }
};
xhr.onload = function() {
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
    console.log('成功 ' + xhr.responseText);
  } else {
    console.warn('失败 ' + xhr.status);
  }
};
xhr.onerror = function() {};
xhr.open('POST', '/upload', true);
xhr.send(file);

// 2

const finalFiles = [];
const fileMaxSize = 1024 * 1024;
Array.from(files).forEach(
  file => file.size < fileMaxSize && finalFiles.push(file)
);

// 3
function setPromise(file) {
  return new Promise(function(resolve) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve(true);
    };
    xhr.onerror = function() {
      resolve(false);
    };

    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
}

const filePromise = Array.from(files).map(file => setPromise(file));
Promise.all(filePromise).then(function(res) {
  res.forEach(r => {
    if (r) {
      console.log('上传成功');
    } else {
      console.log('上传失败');
    }
  });
});
GitHdu commented 5 years ago
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function () {}
xhr.upload.onload = function () {}
xhr.upload.onerror = function () {}
xhr.open('post','/post',true)
xhr.send(file)
Array.from(files).filter((file)=>{
    return file.size/1024/1024 <= 1
})
function promisify(file) {
  return new Promise(function(resolve,reject) {
    var xhr = new XMLHttpRequest().upload;
    xhr.onload = function() {
      resolve(true);
    };
    xhr.onerror = function() {
      reject(false);
    };

    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
}
Promise.all(Array.from(files).map((file)=>{return promisify(file)})).then(res=>{
  // uploaded
}).catch(err => {
  // error
})
livetune commented 5 years ago

第一题

var xhr = new XMLHttpRequest()
// 进度
xhr.onprogress = () => { }
// 失败
xhr.onerror = () => { }
// 成功
xhr.onload = () => { }
xhr.open('POST', '/upload', ture)
xhr.send()

第二题、第三题

let { files } = document.querySelector('[type=file]')
files = [...files].filter(v => v.size <= 1024 * 1024)
console.log(files)
uploadFiles(files).then(res => { console.log(res) }).catch(err => {
    console.log(err)
})
function uploadFiles(files) {
    return Promise.all(files.map(uploadFile))
}
function uploadFile(file) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest()
        const formData = new FormData(file)
        // 失败
        xhr.onerror = () => reject({ status: xhr.statusText, data: xhr.responseText })
        // 成功
        xhr.onload = () => resolve({ status: xhr.statusText, data: xhr.responseText })
        xhr.open('POST', '/upload', ture)
        xhr.send(formData)
    })
}
ziven27 commented 5 years ago

第一题

这个 API 没有实际使用经验,查阅的 MDN

var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload", true);
xhr.onerror = function (e) {
    console.log('失败');
};
xhr.onprogress = function (e) {
    var progress = Math.round(e.loaded / e.total * 100);
    console.log('当前上传进度' + progress + "%");
};
xhr.onload = function () {
    if (xhr.status == 200) {
        console.log('成功');
    } else {
        console.log('失败');
    }
};
xhr.send(file);

第二题

const newFiles= Object.values(files).filter((file)=>file.size < 1024*1024 );

第三题

这道题没有思路

guqianfeng commented 5 years ago

1.

    let xhr = new XMLHttpRequest();
    xhr.upload.onporgress = function(event){
        //event.loaded 加载了多少 event.total总共多少
    };
    xhr.onload = function(){

    };
    xhr.onerror = function(){

    };
    xhr.open("POST", "upload", true);
    xhr.send(file);

2.

    let resultFile = [...files].filter(item => item.size <= 1024 * 1024);

3.

    function uploadPromise(file){
        //返回promise对象,Promise.all语法传入的数组元素都是Promise对象
        return new Promise((resolve, reject)=>{
            let xhr = new XMLHttpRequest();
            xhr.onload = function(){
                resolve();
            };
            xhr.onerror = function(){
                reject();
            };
            xhr.open("POST", "upload", true);
            xhr.send(file);
        })
    }

    Promise.all(resultFile.map(file => uploadPromise(file))).then(()=>{
        //所有的都上传结束了
    })
NeilChen4698 commented 5 years ago

1.

xhr.onprogress = function() {
  //
}
xhr.onload = function() {
  //
}
xhr.onerror = function() {
  //
}

2.

[].filter.call(files, function(ele) {
    return ele.size <= 1024 * 1024;
});

3.

Promise.all([].map.call(files, function(file) {
  return new Promise(function(resolve) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve();
    }
    xhr.onerror = function() {
      resolve();
    }
    xhr.open('POST', '/upload', true);
    xhr.send(file);
  });
})).then(function() {
  console.log('all finished');
});
Seasonley commented 5 years ago
//1
xhr.addEventListener('progress', handleEvent);
xhr.addEventListener('load', handleEvent);
xhr.addEventListener('error', handleEvent);
//2
function fileFilter(files){
    return files.map(file=>file.size/2**20)
}
//3
Promise.all(files.map(v=>requestPromise("POST",'/upload',v)))
.then((values)=>{
    console.log(values);
});
//
function requestPromise(method, url,file) {
    return new Promise(function (resolve) {
        var xhr = new XMLHttpRequest()
        xhr.open(method, url,true)
        xhr.onload = function () {
        if (this.status >= 200 && this.status < 300)
            resolve(xhr.response)
        else
            resolve({status: this.status,statusText: xhr.statusText})
        }
        xhr.onerror = function () {
            resolve({status: this.status,statusText: xhr.statusText})
        }
        xhr.send(file)
    })
}
JaimeCheng commented 5 years ago
// 1
xhr.upload.onprogress = function (e) { }
xhr.onload = function (e) { }
xhr.onerror =  function (e) { }

// 2
var filterFiles = [...files].filter(file => file.size < 1024*1024*1)

// 3 
// I have no idea ╥﹏╥...
Forx-Js commented 5 years ago
  1. 使用onreadystatechange readyState === 4 来判断完成,使用statusText==='OK'判断是否成功
    xhr.onreadystatechange = ({
    currentTarget,
    currentTarget: {
    readyState,
    response,
    statusText
    }
    }) => {
    if (readyState === 4) {
    if (statusText.toLocaleLowerCase() === 'ok') {
      console.log('成功');
    } else {
      console.log('失败');
    }
    }
    };
    // 进度
    xhr.upload.onprogress = (e) => console.log('上传中');
  2. 只留下大于1M的文件
    //zxx: 这里反了哟,应该留下小于1M的
    const fileFilter = Array.prototype.filter.call(files, file => ~~(file.size / 1024 / 1024)
  3. Promise和Promise.all
    
    const uploadXhrList = fileFilter.map(
    (file) => new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    /* ... 代码 
    成功时
    */
    resolve();
    /* ... 代码 
      失败时
    */
    reject();
    /* ...代码 */
    })

) Promise.all(uploadXhrList).then(() => { /统一处理/ })

WGHwebitem commented 5 years ago
<input type="file" id="file"  multiple="multiple" />
1、
    var xhr =new XMLHttpRequest();
    //进度
    xhr.upload.addEventListener('progress',function(event){
        console.log(event)
    })
    //成功
    xhr.upload.addEventListener('load',function(event){
        console.log(event)
    })
    //失败
    xhr.upload.addEventListener('error',function(event){
        console.log(event)
    })
    xhr.open('POST','/upload',true);
    xhr.send(file);

    2、
    var fileid=document.getElementById('file');
    fileid.onchange=function(){
        var fileSize=0;
        var fileMaxSize=1024;
        var filePath=this.value;
        if(filePath){
            fileSize=this.files[0].size;
            var size = fileSize/1024/1024;//1M
            if(size>1){
                alert("文件大小不能大于1M!");
                fileid.value = "";  
            }
        }else{
            return false;
        }
    }   
   3、
    function loadAsk(){
        var xhr =new XMLHttpRequest();
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4 && xhr.status==200){
                document.getElementById('odiv').innerHTML=xhr.responseText;
            }else{
                alert('');
            }
        }
        xhr.open('POST','/upload',true);
        xhr.send();
    }
les-lee commented 5 years ago
1.

var xhr = new XMLHttpRequest();
var uploadTarget = xhr.upload;
// 进度
uploadTarget.onprogress = function (ev) {
}
//成功
uploadTarget.onload = function (e) {
}
//失败
uploadTarget.onerror = function (e) {
}
xhr.open("POST", '/address', true);
xhr.send(file);

2.

let bigger_one_file = [...files].filter(files => {
  return files.size / 1024 / 1024 < 1;
})

3.

// 第一种是次数统计, 成功或者失败都累加, 当提交次数与提交成功次数重合便可以认为是所有图片都上传成功
let uploadLength = 0
function uploadImage(file) {
  var xhr = new XMLHttpRequest();
  var uploadTarget = xhr.upload;
  //成功
  uploadTarget.onload = function (e) {
    uploadLength++
    if (uploadLength === files.length) {
      // all done
    }
  }
  //失败
  uploadTarget.onerror = function () {
    uploadLength++
    if (uploadLength === files.length) {
      // all done
    }
  }
  xhr.open("POST", '/address', true);
  xhr.send(file);
}

files.forEach(file => uploadImage(file))

// 第二种是想到了 promise.all() 不过all 有一个缺点就是一个失败, 就会停止, 此时可以使用 Promise.allSettled() 这个比较新,这个跟all差不多不过他就算有promise失败了也是不会停止的。不过可能兼容性没那么好

function uploadImage(file) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    let uploadTarget = xhr.upload;
    //成功
    uploadTarget.onload = function (e) {
      resolve('success')
    }
    //失败
    uploadTarget.onerror = function () {
      reject('fail')
    }
    xhr.open("POST", '/address', true);
    xhr.send(file);
  })
}

Promise.allSettled(files.map(file => uploadImage(file))).then((results) => {
  results.forEach((result) => console.log(result.status))
  console.log('all done')
})

// 第三种就是使用 一条 promise 去按顺序的进行提交, 直到提交完成,不过需要借助 generator 函数, 比较绕,而且并不是一种好的解法, 因为太慢。。。
// 这里就不再展述了。。。
wingmeng commented 5 years ago

第 1 题:

var xhr = new XMLHttpRequest();

// 上传进度(监听 upload 的 onprogress 事件)
xhr.upload.onprogress = function(e) {
  var percent = e.loaded / e.total * 100
  console.log('上传进度:' + percent + '%');
}

// 请求完成
xhr.onload = function() {
  var resOK = 200;
  console.log('请求完成');

  // 一个完成的请求不一定是成功的请求,故需要判断状态码来确认
  if (xhr.status === resOK) {
    console.log('请求成功')
  }
}

// 请求错误
xhr.onerror = function() {
  console.log('请求失败')
}

xhr.open('POST', '/upload', true);
xhr.send(file);

第 2 题:

var maxFileSize = 1 * (1024 * 1024);  // 1MB

files = [].slice.call(files).filter(function(file) {
  return file.size <= maxFileSize
});

第 3 题:

这里用 Promise.all 方法无疑是最合适的,但看题目中的 js 代码没有使用 ES6+,所以这里用 ES5 规范来实现:

// 这里的 files 是第 2 题中处理过的 files
files.map(uploadImg);

function uploadImg(img) {
  var xhr = new XMLHttpRequest();

  xhr.onload = function() {
    var resOK = 200;

    if (xhr.status === resOK) {
      img._uploaded = true
    }
  }

  xhr.onerror = function() {
    img._uploaded = false
  }

  // 请求结束(无论成功与否)
  xhr.onloadend = checkUpload;

  xhr.open('POST', '/upload', true);
  xhr.send(img);
}

function checkUpload() {
  var isDone = files.every(function(file) {
    return file.hasOwnProperty(_uploaded)
  });

  if (isDone) {
    console.log('上传已结束');

    var result = files.reduce(function(count, cur) {
      count[cur._uploaded ? 'success' : 'fail'] += 1;
      return count;
    }, {
      success: 0,
      fail: 0
    });

    console.log('上传结果:' +
      '成功' + result.success + '个' +
      '失败' + result.fail + '个'
    );

    if (result.success === files.length) {
      console.log('图片全部上传成功')
    }
  }
}
asyncguo commented 5 years ago
  1. xhr.addEventListener('progress', function (e) {
    }, false)
    xhr.addEventListener('load', function (e) {
    }, false)
    xhr.addEventListener('error', function (e) {
    }, false)
    1. [...files].filter(item => item.size <= 1 * 1024 * 1024)
    2. 
      function uploadPromise (file) {
      return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest()

    xhr.addEventListener('progress', function (e) { }, false) xhr.addEventListener('load', function (e) { resolve('success') }, false) xhr.addEventListener('error', function (e) { resolve('error') }, false)

    xhr.open('POST', '/upload', true) xhr.send(file) }) } let xhrArr = [] [...files].map(file => { xhrArr.push(uploadPromise(file)) })

Promise.all(xhrArr).then(res => { }).catch(error => { })

juzhiqiang commented 5 years ago
第一题
上传进度监听
 xhr.upload.addEventListener('progress', function(){}, false);
成功
xhr.addEventListener("load", function(){}, false);
失败
xhr.addEventListener("error", function(){}, false);

第二题
       方法一
       for (let i = 0, i< files.length;i++) {
           if (files[i].size <= 1 * 1024 * 1024) {
                 //小于1M的文件操作在这块
           }
       }

     方法二
        let  filterFiles = [...files].filter(file =>  file.size <= 1*1024*1024);

第三题
      思路是在全局给个计数变量 
      然后再ajax请求内无论是成功还是失败回来就+1 统计最后总数与上传总数相等 则全部上传完成  
ghost commented 5 years ago

1

const xhr = new XMLHttpRequest()
const listen = xhr.upload.addEventListener.bind(xhr.upload)
// 进度
listen('progress', (event) => {
    if (event.lengthComputable) {
        let p = event.loaded / event.total
        console.log('upload percentage', p)
    }
})
// 成功
listen('load', () => {
    console.log('upload success')
})
// 失败
listen('error', () => {
    console.log('upload fail')
})

xhr.open('post', '/upload', true)
xhr.send(file)

2

const filtered = [...files].filter((file) => file.size <= 1024 * 1024)

3

const ajaxUpload = (file, endFunc) => {
    const xhr = new XMLHttpRequest()
    const listen = xhr.upload.addEventListener.bind(xhr.upload)
    // 进度
    listen('progress', (event) => {
        if (event.lengthComputable) {
            let p = event.loaded / event.total
            console.log('upload percentage', p)
        }
    })
    // 成功
    listen('load', () => {
        console.log('upload success')
    })
    // 失败
    listen('error', () => {
        console.log('upload fail')
    })
    // 完成(无论成功或失败)
    listen('loadend', endFunc)

    xhr.open('post', '/upload', true)
    xhr.send(file)
}

let length = files.length
const endFunc = () => {
    length -= 1
    if (length === 0) {
        console.log('all done')
    } else {
        console.log(`${length} file uploading`)
    }
}
for (let i = 0; i < length; i++) {
    let file = files[i]
    ajaxUpload(file, endFunc)
}
sghweb commented 5 years ago
// 第一题
// 进度
function updateProgress(e) {}
// 成功
function transferComplete(e) {}
// 失败
function transferFailed(e) {}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", updateProgress);
xhr.upload.addEventListener("load", transferComplete);
xhr.upload.addEventListener("error", transferFailed);
xhr.open("POST", '/upload', true)
xhr.send(file)

// 第二题
let input = document.querySelector('input')
input.onchange = function(e) {
  console.log(this.files)
  let arr = [...this.files]
  let files = arr.filter(item => {
    return item.size <= 1024 * 1024
  })
  console.log(files)
}

// 第三题
// 初始化一个计数器为count为0,在成功和失败里进行加加,只要count值和files的length一样表示上传结束
xxf1996 commented 5 years ago

只写了逻辑代码,并没有写完整的;

// 第一题
let xhr = new XMLHttpRequest()
xhr.onprogress = e => { // 进度
  // ...
}
xhr.onerror = e => { // 失败
  // ...
}
xhr.onload = e => { // 成功
  // ...
}

// 第二题
let fileList = Array.from(files).filter(file => file.size <= 1024 * 1024)

// 第三题
function uploadImage (file) {
  let xhr = new XMLHttpRequest()
  // ...
  return new Promise((resolve, reject) => {
    xhr.onerror = e => {
      resolve()
    }
    xhr.onload = e => {
      resolve()
    }
  })
}
Promise.all(fileList.map(file => uploadImage(file))).then(() => { // 所有图片上传结束后
  // ...
})
theDrunkFish commented 5 years ago

题目1

var xhr = new XMLHttpRequest();
var upload = xhr.upload;
// 进度
upload.addEventListener('progress', progressHandle, false);

// 成功
upload.addEventListener('load', loadHandle, false);

// 失败
upload.addEventListener('error', errorHandle, false);

xhr.open('POST', '/upload', true);
xhr.send(file);

题目2

var canUploadFiles = [].filter.call(files, function(file){
    return file.size <= 1024 * 1024;
})

题目3(不会)

fzpijl commented 5 years ago

1.

xhr.upload.onprogress = function() {}
xhr.onreadystatechange = function() {
    if(xhr.readystate === 4) {
        if((xhr.status>= 200 && xhr.status < 300) || xhr.status === 304) {}
    }
}
xhr.onerror = function() {}

2.

var oneM = 1024 * 1024;
files = files.filter(file => file.size <= oneM)

3.不会了

silverWolf818 commented 5 years ago
//第一题
var xhr = new XMLHttpRequest();
xhr.onerror = function(){};
xhr.onprogress = function(){};
xhr.onload = function(){};

//第二,三题
document.querySelector('input[type=file]').addEventListener('change',function (e) {
   const files = Array.from(e.target.files).filter(item => {
       return item.size/1024/1024 < 1
   });
    //整体思路就是用计算器来计算成功和失败等于文件总个数。
    var len = files.length;
    var i = 0;
    files.forEach(item => {
        //
        const xhr = new XMLHttpRequest();
        xhr.onload = function(){
            i++;
        };
        xhr.onerror = function(){
            i++;
        };
        xhr.onloadend = function () {
            if(len === i){
                console.log("加载完毕")
            }
        }
    });
},false);
zy017 commented 5 years ago
// 1. 
var xhr = new XMLHttpRequest();
var xhrUpload = xhr.upload;

xhrUpload.addEventListener("progress", function(e){});
xhrUpload.addEventListener("load", function(e){});
xhrUpload.addEventListener("error", function(e){});

xhr.open("POST", '/upload', true);
xhr.send(file);

// 2.
function filterFile(files) {
    return [...files].filter(file => file.size / 1024 /1024 <= 1 )
}
var { files } = document.querySelector('input[type=file]')
var filesFilter = filterFile(files)

// 3.
var uploadPromise = function(file) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest()
        var xhrUpload = xhr.upload
        xhrUpload.addEventListener("progress", function(e){});
        xhrUpload.addEventListener("load", function(e){
            // resolve()
        });
        xhrUpload.addEventListener("error", function(e){
            reject()
        });
        xhrUpload.addEventListener("loadend", function(e){
            resolve()
        });
        xhr.open("POST", '/upload', true);
        xhr.send(file)
    })
}

Promise.all(filesFilter.map(file => uploadPromise(file))).then(values => { 
    console.log(values)
})
liyongleihf2006 commented 5 years ago

这阵子工作有些忙直到现在才有时间来做作业,回答的有些靠后了

第一题

var xhr = new XMLHttpRequest();
//进度
xhr.addEventListener("progress", function (evt) {}, false);
//成功
xhr.addEventListener("load", function (evt) {}, false);
//失败
xhr.addEventListener("error", function (evt) {}, false);
//取消,问题中没有取消,但我顺带也把取消写上吧
xhr.addEventListener("abort", function (evt) {}, false);
//超时,问题中没有超时,但我顺带也把超时写上吧
xhr.addEventListener("timeout", function (evt) {}, false);

xhr.open("POST", '/upload', true);
xhr.send(file);

第二题

//过滤掉大于1M的,所以1M的不能被过滤掉,所以是<=
[...files].filter((file) => file.size <= 1024 * 1024)

第三题

const ajaxPromise = function (file) {
    return new Promise(function (resolve) {
        var xhr = new XMLHttpRequest();

        //成功与失败都触发
        xhr.addEventListener("loadend", function (evt) {
            resolve();
        }, false);

        xhr.open("POST", '/upload', true);
        xhr.send(file);
    });
}

async function uploadCompletes (files) {
    const ajaxPromises = [...files].map(function (file) {
        return ajaxPromise(file);
    })
    for (let i = 0, len = ajaxPromises.length; i < len; i++) {
        await ajaxPromises[i];
    }
}

uploadCompletes(files).finally(function(){
  console.log("上传结束了");
})
frankyeyq commented 5 years ago
1. 
// 进度
xhr.addEventListener('progress', function() {

});
// 成功
xhr.addEventListener('load', function() {

});
// 失败
xhr.addEventListener('error', function() {

});
2. 
files = Array.from(files).filter(file => file.size <= 1024 * 1024)
3.
function uploadFile(file) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.onloadend = function() {
            resolve();
        }
        xhr.open("POST", '/upload', true);
        xhr.send(file);
    });
}
var promises = files.map(uploadFile)
Promise.all(promises).then(res => {
    // 所有的上传都结束了
})
lifelikejuly commented 5 years ago

* 第二题
```JavaScript
var smallFiles = Array.from(files).filter((file) => {
    return file.size <= 1024 * 1024;
});

Promise.all(Array.from(files).filter((file) => { return multipleUpload(file); })).then(res =>{ //成功 }).catch( error =>{ //失败 } );

bugaosunihhh commented 5 years ago

第一题

var xhr = new XMLHttpRequest();
var upload = xhr.upload;
upload.onprogress = function(){

};
upload.onload = function(){

};
upload.onerror = function(){

};

xhr.open();
xhr.send();

第二题

<input type="file" multiple id="files">
<script type="text/javascript">
    document.querySelector("#files").addEventListener("change", function(e){
        let target = e.target;
        let files = target.files;
        // 通过判断 files 里的 size 属性进行过滤;
        let filterFiles = [...files].filter( file => {
            return file.size < 1024*1024;
        });
    })
</script>

第三题

多张上传,有一张上传失败就算结束

var upload = function(file){}{
    return new Promise (resolve, reject){
        var xhr = new XMLHttpRequest();
        var upload = xhr.upload;
        upload.onload = function(){
            resolve()
        };
        upload.onerror = function(){
            reject()
        };
        xhr.open('xxx');
        xhr.send(file);
    }
}

// 只要有一个上传失败,就会catch
Promise.all(filterFiles.map( file => upload(file))).then(res=>{

}).catch(res=>{

})

多张上传,全部结束,不管单张的成功与否

var upload = function(file){}{
    return new Promise (resolve, reject){
        var xhr = new XMLHttpRequest();
        var upload = xhr.upload;
        upload.onload = function(){
            resolve('success')
        };
        upload.onerror = function(){
            resolve('fail')
        };
        xhr.open('xxx');
        xhr.send(file);
    }
}

Promise.all(filterFiles.map( file => upload(file))).then( res =>{
    console.log("全部上传结束");
    var success = res.filter( item => item === 'success' ).length;
    var fail = res.filter( item => item === 'fail' ).length;
    console.log(success+'张成功,'+fail+张'失败')
}).catch(res=>{
    console.log("其他错误")
})
zengqingxiao commented 5 years ago

第一题

    var xhr = new XMLHttpRequest();
    var upload = xhr.upload;
    if (xhr) {
      upload.onprogress = function () { console.log('进度') }
      console.log('进度')
      xhr.open("POST", "/upload", true);//get类型、url、是否异步
      xhr.onreadystatechange = function () {//服务器返回响应时触发
        if (xhr.readyState == 4 && xhr.status == 200) {//返回的类型
          try {
            upload.onload = function () { console.log('获取成功') }
          } catch {
            console.log('运行失败')
          }

        } else {
          upload.onerror = function () { console.log('访问服务器失败') }
        }
      };

      xhr.send(file);
    } else {
      alert("不支持XMLHttpRequest");
    }

第二题

    const newFiles = [].slice.call(files);
    const fileArr = newFiles.filter((item) => {
      return item.size / 1024 / 1024 < 1;
    })

第三题

Promise.all().then(() => { console.log('所有图片上传成功') })
GCGligoudan commented 5 years ago
// 第一题
// 进度
xhr.onprogress = function() {
}
// 成功
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304 ) {
    // 表示请求成功
  }
}
// 表示失败
xhr.onerror = function() {
}

// 第二题
var files = document.querySelector(input[type='file']).files;
[...files].filter((file) => {
  return file.size < 1024 *1024 * 1;
})

// 第三题
var count = 0;
// 对获取到的每个文件进行上传
// 监听上传成功或失败
xhr.onload = function() {
  count ++;
  isFinished(count);
}
xhr.onerror = function() {
  count ++;
  isFinished(count);
}
function isFinished(count) {
  if (count === files.length){
    // 所有的请求已经结束
  }
}
kuikuiGe commented 5 years ago

//1.

xhr.upload.onprogress = function(event){
    if(event.lengthComputable){
        console.log('上传进度:'+event.loaded+'/'+event.total)
    }
}

xhr.onreadystatechange = function(event){
    if (xhr.readyState == 4) {
        if (xhr.status == 200) {
            console.log("上传成功")
        }else{
            console.log("上传失败")
        }
    }
}

//2.

var filterFiles = [].slice.call(files).filter(file=>{
    return file.size > 1 * 1024 * 1024
})

//3.

var filterFiles = [],
    currFiles = [];

document.getElementById("test").onchange = function(){
    var files = document.getElementById('test').files;

    filterFiles = [].slice.call(files).filter(file=>{
        return file.size > 1 * 1024 * 1024
    })

    currFiles = filterFiles

    for(var i=0;i<filterFiles.length;i++){
        (function(file){
            uploadFile(file)
        }(filterFiles[i]))
    }
}

function deleteFile(files,file){
    var result = [];
    for(var i=0;i<files.length;i++){
        if(files[i] != file){
            result.push(files[i])
        }
    }     

    return result
}

function uploadFile(file){
    var formData = new FormData()

    formData.append('file',file)

    var xhr = new XMLHttpRequest();

    xhr.upload.onprogress = function(event){
        if(event.lengthComputable){
            console.log(file.name+'进度条:'+event.loaded+'/'+event.total)
        }
    }

    xhr.onreadystatechange = function(event){
        if (xhr.readyState == 4) {
            currFiles = deleteFile(currFiles,file)
            if (currFiles.length==0){
                console.log("所有图片都上传结束")
            }
        }
    }

    xhr.open('POST','/upload',true)
    xhr.send(formData)
}
zhangxinxu commented 5 years ago

本期要点:

  1. xhr.onprogress和xhr.upload.onprogress的区别:这两个都能显示进度百分比,但是,前者显示的是服务器返回的数据,后者是发送给服务器的。例如,我们ajax get一张图片,则前者合适;如果我们是ajax post上传一张图片,则后者合适。
  2. event.target.files是一个选择文件对象类数组,适合使用filter进行过滤,然后文件大小直接file.size就有,file.name是文件名。
  3. onloadend回调,这个成功和失败都会触发。Promise.all是比较好的方法,但是有兼容性。 xhr.onerror = function() { resolve(false); } 不推荐,xhr.onerror = function() { reject(false); } + Promise.all则是有问题,会中断,可以使用Promise.allSettled() 这个比较新的特性。
  4. 传统的计数器实现,每完成一个loadend,则计数变化一位,直到和files.length匹配。
  5. 小礼物。GMTC全球大前端技术大会现场演讲视频(部分讲师不允许对外公布视频除外)兑换码,月底到期,突然想起来,送给大家。规则是:第一个在两个微信群发出:把你的微信昵称写在CSS世界任意一页,拍照发到群里,第一位小伙伴可以获得。
tao1874 commented 5 years ago

第一题

xhr.onprogress = function(event) {}
xhr.onload = function(event) {}
xhr.onerror = function(event) {}

第二题

const filterFiles = Array.from(this.files).filter( e => e.size < 1024 * 1024 )

第三题

const filterFiles = Array.from(this.files).filter(e => e.size < 1024 * 1024)
        const uploads = filterFiles.map(file => {
            return new Promise((resolve, reject) => {
                var xhr = new XMLHttpRequest()
                xhr.onload = function (event) {
                    resolve(event)
                }
                xhr.onerror = function (event) {
                    reject(event)
                }
                xhr.open("post", "./upload")
                xhr.send(file)
            })
        })
Promise.all(uploads).then(res => {
                console.log("ok")
        }).catch(err => {
                console.log("error")
            })
        })