zoukankan      html  css  js  c++  java
  • 原生js上传图片遇到的坑(axios封装)

    后台给我写了一个上传图片的接口,自己用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>
    View Code

    因为这样用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="">路径&nbsp;:</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;
         100%
    }
    
    .param-pannel>div {
        padding: 5px 0;
    }
    </style>
    
    
    <style scoped lang="scss">
    @import '../../../assets/css/params_common.scss';
    </style>
    View Code

    封装的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
    View Code

    封装的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() {}
      })
    }
    View Code

  • 相关阅读:
    【Vue】状态管理
    【Vue】路由
    【Vue】组件
    【Vue】基础(数据 & 计算属性 & 方法)
    【Vue】基础(虚拟DOM & 响应式原理)
    【Vue】基础(生命周期 & 常用指令)
    【Vue】搭建开发环境
    【Mongodb】事务
    【Mongodb】视图 && 索引
    【Mongodb】聚合查询 && 固定集合
  • 原文地址:https://www.cnblogs.com/pengfei25/p/11907750.html
Copyright © 2011-2022 走看看