原生js上传图片遇到的坑
Posted 人在路途
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生js上传图片遇到的坑相关的知识,希望对你有一定的参考价值。
后台给我写了一个上传图片的接口,自己用form表单测试成功
接口可以正常跳转
测试的代码:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Document</title> </head> <body> <form method="POST" action="http://192.168.79.191:8889/api/upload/uploadFile" enctype="multipart/form-data"> <table> <tr> <td><label path="file">Select a file to upload</label></td> <td><input type="file" name="file" id="upload_file"/></td> </tr> <tr> <td>fileGroup: <input name = "fileGroup" type = "text"><br></td> </tr> <tr> <td>flag:<input name = "flag" type = "text"><br></td> </tr> <tr> <td><input type="submit" value="Submit"/></td> </tr> </table> </form> </body> </html>
因为这样用form表单提交的时候会自动跳转,所以就想到用js模拟form表单提交
代码一写完,问题来了,用axios请求不成功,
let file = e.target.files[0] var formData = new FormData() formData.append(\'file\', file) this.$ajax.post(Api.uploadFile, formData).then(function(response) { alert(123) //this.$refs.loading.show() if (response.data.status === -1) { //this.promptText = response.data.msg //this.$refs.prompt.show() } else { //this.front_pic = this.publicUrl + response.data.data.url // 提交图片获取URL,返回 } }, function() { this.promptText = \'请求失败\' this.$refs.prompt.show() })
然后我想axios不成功,那我换成了原生的ajax请求应该行了吧结果还是不成功,代码如下
/*原生请求方式 */ let xhr = new XMLHttpRequest(); // XMLHttpRequest 对象 xhr.open("post", "http://localhost:8082/api/files/api/upload/uploadFile", true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。 xhr.setRequestHeader(\'content-type\', \'multipart/form-data\')//不要自作多情加上这一句 //xhr.setRequestHeader(\'Accept\', \'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\') xhr.send(formData); //开始上传,发送form数据 xhr.onreadystatechange = function () { var data = xhr.responseText; console.log(data); }
控制台 network 就是请求不成功,500报错
错误信息如下
整了大半天,最后发现是不用设置content-type 一去掉就正常了 真的是自作多情 自己设置了content-type导致请求不成功
总结问题:
第一:axios不成功
原因:
1、自作多情设置了content-type(拦截器李阿敏)
//http request 拦截器 axios.interceptors.request.use( config => { config.headers = { //\'Content-Type\':\'application/x-www-form-urlencoded\' \'Content-Type\': \'multipart/form-data\' } return config; }, error => { return Promise.reject(err); } );
2、axios可能将请求污染
解决办法:
请求之前先new 一个全新的axios 如下
uploadImage(e){ let instance = axios.create();//请求之前先new一个全新的axios let file = e.target.files[0] const formDate = new FormData() formDate.append(\'file\', file) instance.post(\'/files/api/upload/uploadFile\',formDate).then((res)=>{ console.log(res); if(res.status && res.status == 500){ this.error=\'用户名或密码错误!\' }else if(res.access_token){ let millisecond = new Date(new Date().getTime() + res.expires_in * 1000); //access_token过期时间 cookies.set(\'access_token\',res.access_token,{expires: millisecond}); //设置cookie this.$router.replace("/"); //登录到首页 } }) }
上面代码:正常,可以请求成功,问题得到解决
第二:原生的ajax不成功
原因 设置了content-type
解决办法:将content-type去掉
上传图片组件代码
<template> <div class="param-pannel"> <common-prm/> <border-prm myStyle="style" /> <collapse-item title="图片"> <div class="param-gap"> <label class="left" for="">路径 :</label> <div class="right"> <input type="file" name="file" ref="input" enctype="multipart/form-data" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg" multiple="multiple" @change="getFile" class="data-value" /> </div> </div> </collapse-item> </div> </template> <script> import axios from \'axios\' import mixins from \'../paramMixins.js\' import Api from \'@frameworks/conf/api\' export default { name: \'ImgParam\', mixins: [mixins], data() { return { textName: \'文本\' } }, methods: { getFile(e) { //验证 if (e.target.files[0].size >= 1048576) { alert("上传图片大小不得超过1M"); return false; } // 预览图片 var reader = new FileReader(); let _this = this reader.onload = (function(file) { return function(e) { var datainfo = this.result; _this.params.images = datainfo _this.updateData() }; })(e.target.files[0]); reader.readAsDataURL(e.target.files[0]); //上传 this.upload(e.target.files[0]) }, //调用上传图片的接口上传 upload(file){ var formData = new FormData() formData.append(\'file\', file) /*axios请求方式 */ this.$ajax.upload(Api.uploadFile, formData).then(function(response) { if (response.data.status === -1) { alert() } else { } }, function() { this.promptText = \'请求失败\' this.$refs.prompt.show() }) //axios封装的post请求(不成功) /*this.$ajax.post(Api.uploadFile, formData).then(function(response) { alert(123) }, function() { this.promptText = \'请求失败\' this.$refs.prompt.show() })*/ /*原生请求方式(成功) */ // let xhr = new XMLHttpRequest(); // XMLHttpRequest 对象 // xhr.open("post", "http://localhost:8082/api/files/api/upload/uploadFile", true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。 // //xhr.setRequestHeader(\'content-type\', \'multipart/form-data\') // //xhr.setRequestHeader(\'Accept\', \'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\') // xhr.send(formData); //开始上传,发送form数据 // xhr.onreadystatechange = function () { // var data = xhr.responseText; // console.log(data); // } } } } </script> <style scoped lang="scss"> .param-pannel input, .param-pannel select { border: 1px solid #ddd; width: 100% } .param-pannel>div { padding: 5px 0; } </style> <style scoped lang="scss"> @import \'../../../assets/css/params_common.scss\'; </style>
封装的axios
import axios from \'axios\'; import {axios_defaults_timeout} from \'@frameworks/conf/config\' import qs from \'qs\' axios.defaults.timeout = axios_defaults_timeout; axios.defaults.baseURL = JSON.parse(process.env.VUE_APP_MICRO_SERVICE)?process.env.VUE_APP_URL:process.env.VUE_APP_SINGLEURL; //填写域名 //http request 拦截器 axios.interceptors.request.use( config => { config.headers = { //\'Content-Type\':\'application/x-www-form-urlencoded\' \'Content-Type\': \'multipart/form-data\' } return config; }, error => { return Promise.reject(err); } ); //响应拦截器即异常处理 axios.interceptors.response.use(response => { return response }, err => { if (err && err.response) { switch (err.response.status) { case 400: return Promise.resolve({status:err.response.status,message:\'错误请求\'}); break; case 401: return Promise.resolve({status:err.response.status,message:\'未授权,请重新登录\'}); break; case 403: return Promise.resolve({status:err.response.status,message:\'拒绝访问\'}); break; case 404: return Promise.resolve({status:err.response.status,message:\'请求错误,未找到该资源\'}); break; case 405: return Promise.resolve({status:err.response.status,message:\'请求方法未允许\'}); break; case 408: return Promise.resolve({status:err.response.status,message:\'请求超时\'}); break; case 500: return Promise.resolve({status:err.response.status,message:\'服务器端出错\'}); break; case 501: return Promise.resolve({status:err.response.status,message:\'网络未实现\'}); break; case 502: return Promise.resolve({status:err.response.status,message:\'网络错误\'}); break; case 503: return Promise.resolve({status:err.response.status,message:\'服务不可用\'}); break; case 504: return Promise.resolve({status:err.response.status,message:\'网络超时\'}); break; case 505: return Promise.resolve({status:err.response.status,message:\'http版本不支持该请求\'}); break; default: return Promise.resolve({status:err.response.status,message:\'未知错误\'}); break; } } else { return Promise.resolve({status:err.response.status,message:\'连接到服务器失败\'}); } return Promise.resolve(err.response) }) /** * 封装get方法 * @param url * @param data * @returns {Promise} */ export function fetch(url,params={}){ return new Promise((resolve,reject) => { axios.get(url,{ params:params }) .then(response => { if(response.data) resolve(response.data); }) .catch(err => { reject(err) }) }) } /** * 封装上传图片upload的方法 * @param url * @param data * @returns {Promise} */ export function upload(url,data = {}){ let instance = axios.create(); return new Promise((resolve,reject) => { instance.post(url,data) .then(response => { if(response.data) resolve(response.data); },err => { reject(err) }) }) } /** * 封装post请求 * @param url * @param data * @returns {Promise} */ export function post(url,data = {}){ return new Promise((resolve,reject) => { axios.post(url,qs.stringify(data)) .then(response => { if(response.data) resolve(response.data); },err => { reject(err) }) }) } /** * 封装patch请求 * @param url * @param data * @returns {Promise} */ export function patch(url,data = {}){ return new Promise((resolve,reject) => { axios.patch(url,data) .then(response => { if(response.data) resolve(response.data); },err => { reject(err) }) }) } /** * 封装put请求 * @param url * @param data * @returns {Promise} */ export function put(url,data = {}){ return new Promise((resolve,reject) => { axios.put(url,data) .then(response => { if(response.data) resolve(response.data); },err => { reject(err) }) }) } /** * 封装delete请求 * @param url * @param data * @returns {Promise} */ export function del(url,data = {}){ return new Promise((resolve,reject) => { axios.delete(url,data) .then(response => { if(response.data) resolve(response.data); },err => { reject(err) }) }) } /** * 封装异步Ajax请求 * @param url * @param data * @returns {Promise} */ export async function syncAjax (url = \'\',method = \'get\',data = {},callbackr = ()=>{},callbackw = ()=>{}) { try { let response = await axios({ method, url, data }) callbackr && callbackr(response) return Promise.resolve(response) } catch (err) { callbackw && callbackw(err) return Promise.reject(err) } } const ajax = { fetch,post,patch,put,del,syncAjax,upload } export default ajax
封装的jq ajax
import $ from \'jquery\'; export default function jqueryAjax(url,method,async,data,callbackr,callbackw) { $.ajax({ url: url, //url路径 type: method, //GET async: async, //或false,是否异步 data: data, timeout: 5000, //超时时间 dataType: \'json\', //返回的数据格式 beforeSend: function(xhr) {}, success: function(data, textStatus, jqXHR) { callbackr && callbackr(data); }, error: function(xhr, textStatus) { callbackw && callbackw(xhr); }, complete: function() {} }) }
以上是关于原生js上传图片遇到的坑的主要内容,如果未能解决你的问题,请参考以下文章