仿造vue-resource的formdata傳對象

衆插件不支持同步,也是沒辦法的事情,具體爲啥就不分析了,確實搞不懂。vue

一直用vue-resource的post,以爲很舒服。數組

然,沒辦法只能仿造一個,本身提供一個同步方法promise

幾個點先擺清楚數據結構

1. .then()方法:幾經百度,原來是Promise套路,原諒個人無知,可能不是什麼新鮮事物,不曉得的同窗本身百度一下吧。不是很複雜。app

2. formdata,用法滿天飛,搞到最後也是暈乎乎,畢竟模擬Form提交時並無太深層的嵌套數據結構,基本上是值對,like name = 'zhang' gander = '1' 這種的數據。對於比較深層的嵌套數據,一臉矇蔽的百度不到解法。舉個例子{list:[{a:1,b:2},{a:2,b:1}]},一句話,也是個雞肋。(沒深究,莫笑愚淺薄,腦殼不夠用)函數

3. 額,第三是啥來着,二胡了,算了。vue-resource

想仿造先分析,說實話寫這個文壓力有點大,可能有更簡潔的辦法去分析,哥不會。post

按理說,去看源碼應該是最省事的,沒準還能找到一步到位的方法,哥早已經被源碼繞暈了,原來js還能那麼寫,大神!!this

仍是按照哥的套路來吧。url

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            
    }    
}
相關文章
相關標籤/搜索