zoukankan      html  css  js  c++  java
  • 仿造vue-resource的formdata传对象

    众插件不支持同步,也是没办法的事情,具体为啥就不分析了,确实搞不懂。

    一直用vue-resource的post,觉得很舒服。

    然,没办法只能仿造一个,自己提供一个同步方法

    几个点先摆清楚

    1. .then()方法:几经百度,原来是Promise套路,原谅我的无知,可能不是什么新鲜事物,不晓得的同学自己百度一下吧。不是很复杂。

    2. formdata,用法满天飞,搞到最后也是晕乎乎,毕竟模拟Form提交时并没有太深层的嵌套数据结构,基本上是值对,like name = 'zhang' gander = '1' 这种的数据。对于比较深层的嵌套数据,一脸蒙蔽的百度不到解法。举个例子{list:[{a:1,b:2},{a:2,b:1}]},一句话,也是个鸡肋。(没深究,莫笑愚浅薄,脑袋不够用)

    3. 额,第三是啥来着,二胡了,算了。

    想仿造先分析,说实话写这个文压力有点大,可能有更简洁的办法去分析,哥不会。

    按理说,去看源码应该是最省事的,没准还能找到一步到位的方法,哥早已经被源码绕晕了,原来js还能那么写,大神!!

    还是按照哥的套路来吧。

    1. 数据:formdata数据,并不一定要用FormData去造,这是我最先想到的。跟踪一下,什么秘密都没有。

    formdata 结构就是如此,点 view source 有更详细的源码

    不要怕,看到这些应该高兴才是,这是encodeURIComponent的结果,可以用decodeURIComponent来翻译

    list[0][dirname]=D:/xampp/htdocs/wnds/sound&list[0][basename]=error_tips.mp3&list[0][extension]=mp3&list[0][filename]=error_tips&list[0][isSelected][value]=true&list[0][type]=file&list[0][img]=images/file_icon/icon_file/file.png&list[1][dirname]=D:/xampp/htdocs/wnds/sound&list[1][basename]=file_remove.mp3&list[1][extension]=mp3&list[1][filename]=file_remove&list[1][isSelected][value]=true&list[1][type]=file&list[1][img]=images/file_icon/icon_file/file.png&list[2][dirname]=D:/xampp/htdocs/wnds/sound&list[2][basename]=folder_open.mp3&list[2][extension]=mp3&list[2][filename]=folder_open&list[2][isSelected][value]=true&list[2][type]=file&list[2][img]=images/file_icon/icon_file/file.png&list[3][dirname]=D:/xampp/htdocs/wnds/sound&list[3][basename]=recycle_clear.mp3&list[3][extension]=mp3&list[3][filename]=recycle_clear&list[3][isSelected][value]=true&list[3][type]=file&list[3][img]=images/file_icon/icon_file/file.png

    你看,翻译完了,就都清楚了,这是一个字符串,配合类结构可以知道,这是每个变量的串接。

    list[0][dirname]=D:/xampp/htdocs/wnds/sound
    细看这个,这是一个变量和它的路径的表示,这个变量值位于整个数据中的路径就是前面的各种下标和名称。
    请注意,我把路径一词加大了,这就是一个路径问题。通过一系列嵌套计算,就可以得到的。
    也就是说,formdata的数据结构就是 路径 = 值 & 路径 = 值


    分析到这里,一切都是那么的宁静安详,预示着,问题解开了。(问题不是关键,关键是分析的过程,啊哈哈哈哈)


    那么如何去构造它呢?
    一个函数足以搞定

    function trans(data,key = ''){
        var ret = ""                
        if(typeof data == 'object'){
            for(let it in data){
                ret += trans(data[it],key + (key == ''?it:"["+ it + "]"))                    
            }
        }else if(Array.isArray(data)){
            for(var i = 0;i < data.length;i++){
                ret += trans(data[i],key + "[" + i + "]") 
            }
        }else{
            ret +=encodeURIComponent( key) + '=' + encodeURIComponent(data)  + "&" 
        }
        return ret            
    }

    简单伐?

    几点注意,都是我填坑填出来的。

    1. 最外层是没有[]的,所有路径最外层是没有[]的表示一个数组的名称。

    2. 所有=都没有被翻译成urlstring

    如此

    最大的问题解决了,我们构造了一个formdata,那么将这个formdata传出去即可了。

    完整的代码分享一下,请不要学我的不规范,完成自己的js文件

    var gp = {
        get: function(url) {
            return this._get(url, true)
        },
        synget: function(url) {
            return this._get(url, false)
        },
        _get: function(url, syn) {
            const promise = new Promise(function(resolve, reject) {
                const handler = function() {
                    if(this.readyState !== 4) {
                        return;
                    }
                    if(this.status === 200) {
                        resolve(this.response);
                    } else {
                        reject(new Error(this.statusText));
                    }
                }
                var request = new XMLHttpRequest()
                request.open('GET', url, syn)
                request.onreadystatechange = handler
                request.send(null)
            })
            return promise
        },
        post: function(url, data) {
            return this._post(url, data, true)
        },
        synpost: function(url, data) {
            return this._post(url, data, false)
        },
        _post: function(url, data, syn) {
            const promise = new Promise(function(resolve, reject) {
                const handler = function() {
                    if(this.readyState !== 4) {
                        return;
                    }
                    if(this.status === 200) {
                        resolve(this.response);
                    } else {
                        reject(new Error(this.statusText));
                    }
                }
                var request = new XMLHttpRequest()
                request.open('POST', url, syn)            
                request.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
                request.onreadystatechange = handler
                
                
                var ret = gp._trans(data)
                
                request.send(ret.substr(0,ret.length-1))
            })
            return promise
        },
        _trans : function(data,key = ''){
            var ret = ""                
            if(typeof data == 'object'){
                for(let it in data){
                    ret += gp._trans(data[it],key + (key == ''?it:"["+ it + "]"))                    
                }
            }else if(Array.isArray(data)){
                for(var i = 0;i < data.length;i++){
                    ret += gp._trans(data[i],key + "[" + i + "]") 
                }
            }else{
                ret +=encodeURIComponent( key) + '=' + encodeURIComponent(data)  + "&" 
            }
            return ret            
        }    
    }
  • 相关阅读:
    jquery
    gulp 入门
    bower 教程
    webstrom管理git
    修改页面浏览器自动刷新
    兼容IE低版本
    js之触屏事件篇
    js之日期篇
    设置浏览器默认样式
    Listview四种视图VIEW
  • 原文地址:https://www.cnblogs.com/allofalan/p/9968131.html
Copyright © 2011-2022 走看看