久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    簡便無刷新文件上傳系統 - cloudgamer - 博客園

     遙遠的橋zz 2011-04-30

    之前寫過一個仿163網盤無刷新多文件上傳系統,已經對無刷新上傳文件的原理做了詳細的分析。
    而這次的系統主要是針對單個file控件的,便攜版,使用更簡單,還有更深入的分析。
    ps:flash實現的效果是好得多,但這不是我研究的范圍,也沒什么可比性。

    兼容:ie6/7/8, firefox 3.5.5, opera 10.01, safari 4.0.3, chrome 3.0

    12月2號是我女朋友的生日,祝她開心快樂每一天,一起創造幸福的未來,并感謝各位的祝福!


    效果預覽

    文件上傳
    選擇文件 重命名 操作 狀態
    重置 選擇文件
    重置 選擇文件
    重置 選擇文件

    ps:由于需要后臺,要測試系統請下載實例測試。
    ps2:在完整實例文件中,還有一個文件屬性查看實例。


    程序說明

    【upload】

    程序中最重要的方法就是upload了,調用它就可以進行無刷新上傳。
    upload的過程是這樣的,首先用stop方法停止上一次上傳,并判斷是否選擇文件。
    然后分別調用_setIframe,_setForm和_setInput,生成需要的iframe,form和input。

    如果設置了timeout屬性的話,會自動設置計時器:

    if ( this.timeout > 0 ) {
        
    this._timer = setTimeout( $$F.bind(this._timeout, this), this.timeout * 1000 );
    }

    ps:經測試,小于0的延時時間,ie會取消執行,而其他瀏覽器會當成0執行。

    程序有一個_sending屬性用來判斷上傳狀態。
    在stop(停止),dispose(銷毀),_finis(完成),_timeout(超時)時會把它設為false。
    而在上傳開始前要把它設置為true。

    最后提交表單就開始上傳了。


    【iframe】

    程序使用_setIframe函數來創建無刷新需要的iframe。

    由于ie中iframe的name不能修改的問題,要這樣創建iframe:  


    var iframename = "QUICKUPLOAD_" + QuickUpload._counter++,
        iframe 
    = document.createElement( $$B.ie ? "<iframe name=\"" + iframename + "\">" : "iframe");
    iframe.name 
    = iframename;
    iframe.style.display 
    = "none";

    ps:關于iframe的name的問題參考這里的iframe部分
    ie8已經可以修改name了,但在非標準(怪辟)模式下還是不能修改。
    其中使用了一個QuickUpload函數自身的_counter屬性做計算器,這就能保證各個實例的iframe的name就不會重復。

    為了能在文件上傳完成后執行回調函數,會在iframe的onload中執行_finish函數:


    var finish = this._fFINISH = $$F.bind(this._finish, this);
    if ( $$B.ie ) {
        iframe.attachEvent( 
    "onload", finish );
    else {
        iframe.onload 
    = $$B.opera ? function(){ this.onload = finish; } : finish;
    }


    在ie需要用attachEvent來綁定onload,因為在ie中直接設置onload是無效的。
    除了用attachEvent還可以用onreadystatechange代替。
    至于原因我也不清楚,詳細參考“判斷 iframe 是否加載完成的完美方法”。

    iframe的加載還有一個問題,測試以下代碼:


    <body><div id="msg">狀態:</div></body>
    <script>
    var msg = document.getElementById("msg");
    var iframe = document.createElement("iframe");
    iframe.onload 
    = function(){ msg.innerHTML += "onload,"; }
    document.body.appendChild(iframe);
    iframe.src 
    = "http://cloudgamer.cnblogs.com/"
    </script>


    結果safari, chrome都會觸發onload兩次,而opera, ff和ie(請自行兼容)都是1次。

    估計在safari和chrome在appendChild之后就進行第一次加載,并且在設置src之前加載完畢,所以觸發了兩次。
    如果在插入body之前給iframe隨便設置一個src(除了空值),間接加長第一次加載,那么也只觸發一次了。
    ps:不設置或空值的src相當于鏈接到“about:blank”(空白頁)。

    那么opera, ff和ie可能是第一次加載太慢,第二次覆蓋了第一次的,所以只觸發了一次onload。
    ps:也可能是其他原因,例如瀏覽器優化之類的,我也不確定。

    針對加載過快的問題,可以在onload的時候根據_sending確定之前是否上傳狀態來解決。
    雖然沒測試出來,會不會有_sending設置之后submit之前剛好觸發第一次onload的情況呢?
    針對這個問題,在upload方法中會把_sending放在submit之后設置。
    那如果在submit之后_sending設置之前就觸發了onload呢?(...囧)
    這個情況基本不會出現,如果真的出現,就把_sending設置放到submit前面吧。

    opera還有一個麻煩的問題,測試下面代碼:


    <body>
    <div id="msg">狀態:</div>
    <form action="http://cloudgamer.cnblogs.com/" target="ifr">
    </form>
    </body>
    <script>
    var msg = document.getElementById("msg");
    var iframe = document.createElement("iframe");
    iframe.name 
    = "ifr";
    iframe.onload 
    = function(){ msg.innerHTML += "onload,"; }
    document.body.appendChild(iframe);
    msg.innerHTML 
    += "submit,";
    document.forms[
    0].submit();
    </script>


    ie和ff顯示submit,onload,safari和chrome顯示的是onload,submit,onload,跟上面的分析一致。
    而opera卻顯示submit,onload,onload,兩次onload都是在submit之后觸發的。
    這個情況就不能單純用_sending來解決了。
    是不是submit不能使iframe取消加載呢?
    在appendChild之前設一個src,結果正常的只觸發onload一次,看來是可以的啊。

    雖然不知道原因,辦法還是有的,一個是appendChild前設一個src,還可以在第一次onload中重新設置onload,像程序那樣。
    但這兩個方法都存在不確定性,不能完全解決問題,但也找不到更好的方法了。

    ff的onload還有一個問題,在出現ERROR_INTERNET_CONNECTION_RESET(文件大小超過服務器限制)之類的服務器錯誤時,即使加載完成也不會觸發onload,暫時找不到解決辦法。

    iframe有一個缺陷是只能用onload判斷加載完成,但沒有辦法判斷是否加載成功。
    沒有類似XMLHTTP的status的東西,遇上404之類的錯誤也沒辦法判別出來。
    在使用時要做好這方面的處理,例如說明允許上傳文件大小,超時時間,如何處理長時間無響應等。


    【form】

    程序使用_setForm函數來創建用來提交數據的form。

    要實現無刷新上傳,要對form進行特殊的處理:

    $$.extend(form, {
        target: 
    this._iframe.name, method: "post", encoding: "multipart/form-data"
    });

    ps:詳細看這里的無刷新上傳部分

    由于form是手動插入的,為了不影響原來頁面布局還要設置一下form樣式,使它“隱形”起來:

    $$D.setStyle(form, {
        padding: 
    0, margin: 0, border: 0,
        backgroundColor: 
    "transparent", display: "inline"
    });


    還要注意的是,同一個表單控件只能對應一個form。
    如果file控件本身已經有一個form的話,必須在提交前移除:

    file.form && $$E.addEvent(file.form, "submit", $$F.bind(this.dispose, this));

    dispose方法是用來銷毀程序的,包括移除form。
    ps:如果提交前submit被覆蓋的話要手動執行一次dispose方法。

    最后把form插入到dom: 

    file.parentNode.insertBefore(form, file).appendChild(file);

    先把form插入到file控件之前,然后把file插入到form,這樣就能保證file在原來的位置上了。


    【input】

    如果有其他參數要傳遞,程序會使用_setInput函數來創建傳遞數據的表單控件。

    由于生成的form里面只有file控件,要傳遞其他參數只能用程序生成了。
    程序用一個_inputs集合來保存當前在form中生成的表單控件。

    首先根據自定義的parameter屬性創建表單控件:


    for ( name in this.parameter ) {
        
    var input = form[name];
        
    if ( !input ) {
            input 
    = document.createElement("input");
            input.name 
    = name; input.type = "hidden";
            form.appendChild(input);
        }
        input.value 
    = this.parameter[name];
        newInputs[name] 
    = input;
        
    delete oldInputs[name];
    }


    當form中沒有對應name的控件時,會自動生成一個hidden控件插入到form中。
    其中newInputs是用來記錄當前生成的控件的,而oldInputs就是_inputs集合。
    當設置過對應name的控件后,就從oldInputs中刪除對應控件的關聯。

    然后移除oldInputs關聯的控件:

    for ( name in oldInputs ) { form.removeChild( oldInputs[name] ); }

    這樣就能移除上一次生成的無用的控件了。

    最后重新記錄當前控件到_inputs方便下次使用。


    【stop】

    如果想停止當前上傳操作,可以調用stop方法。

    一般來說當iframe發生重載時,會取消上一次的載入,那么只要重新設置src就能取消上傳了。
    測試以下代碼:


    <body>
    <iframe id="ifr" name="ifr"></iframe>
    <form action="http://cloudgamer.cnblogs.com/" target="ifr">
    </form>
    </body>
    <script>
    document.forms[
    0].submit();
    document.getElementById(
    "ifr").src = "";
    </script>


    結果都能取消加載,除了opera,未知什么原因。
    有兩個方法解決,一個是通過form隨便用一個action提交一次,還有就是直接移除iframe。
    后一個方法比較方便,程序中用_removeIframe方法直接移除iframe。
    ps:有更好方法的話記得告訴我。


    【dispose】

    當使用結束或其他原因要銷毀程序時,可以調用dispose方法。

    dispose里面主要做的是移除iframe和form。
    移除iframe用的是_removeIframe方法,首先把onload移除,再把iframe從body移除:

    var iframe = this._iframe;
    $$B.ie 
    ? iframe.detachEvent( "onload"this._fFINISH ) : ( iframe.onload = null );
    document.body.removeChild(iframe); 
    this._iframe = null;

    十分簡單,但在ff有一個問題,測試以下代碼:


    <form target="ifr" action="x">
        
    <input id="btn" type="submit" value="click">
    </form>
    <iframe name="ifr" id="ifr"></iframe>
    <script>
    document.getElementById(
    "btn").onclick = function(){
        document.getElementById(
    "ifr").onload = function(){
            
    this.parentNode.removeChild(this);
        };
    }
    </script>


    提交后都能移除iframe,但ff還一直顯示“載入中”的狀態。
    不過解決方法也很簡單,用setTimeout設置一個延時,讓iframe執行完整就可以了。
    所以在dispose中是這樣調用_removeIframe的:

    if ( $$B.firefox ) {
        setTimeout($$F.bind(
    this._removeIframe, this), 0);
    else {
        
    this._removeIframe();
    }


    至于form的移除就比較簡單,在_removeForm這樣處理:

    var form = this._form, parent = form.parentNode;
    if ( parent ) {
        parent.insertBefore(
    this.file, form); parent.removeChild(form);
    }
    this._form = this._inputs = null;


    要判斷一下parentNode,否則如果parentNode不存在的話后面的會執行出錯。


    【file的reset】

    在實例里,有一個用來重置file控件的ResetFile函數。

    重置file控件一般的辦法是使所在的form執行reset,但問題是會把其他表單控件也重置了。
    以前由于安全問題,file的value是不允許修改的。
    但現在ff,chrome和safari可以把它設為空值來實現重置:

    file.value = "";

    當然其他值還是不允許的。
    ps:記憶中以前是不行的,不知有沒有記錯。

    對于opera,有一個變通的方法,利用它的type屬性:

    file.type = "text"; file.type = "file";

    通過修改type得到的file控件,value會自動還原成空值,這樣就間接把file控件清空了。
    ps:利用這個方法可以間接得到文件路徑,但由于變回去后值就清空了,所以沒什么用。

    而ie的表單控件的type設置后是不允許修改的,不能用opera的辦法。
    不過還是有以下方法解決:
    1,新建一個form,把file插進入后reset,再移除:

    with(file.parentNode.insertBefore(document.createElement('form'), file)){
        appendChild(file); reset(); removeNode(
    false);
    }

    好處是使用原生的reset,穩定可靠,但效率低。
    ps:removeNode只有ie和opera支持,如需兼容可改用removeChild的方式。

    2,利用outerHTML,重建一個file控件:

    file.outerHTML = file.outerHTML;

    好處是高效,但由于是新創建的file控件,之前關聯的東西都丟失了。
    ps:ff支持不支持outerHTML。

    3,利用cloneNode,復制一個file控件:

    file.parentNode.replaceChild(file.cloneNode(false), file);

    跟上一個方法差不多,但效率更低。

    4,利用select方法選中file控件的文本域,再進行清空:

    file.select(); document.selection.clear();

    file.select(); document.selection.clear();

    看來沒什么問題,但file必須能被select(不能是隱藏狀態)。
    ps:這兩個方法都只能在ie使用。

    由于程序中file是需要關聯的,所以方法2和3都不能用。
    方法4貌似也不錯,但有一個致命問題,在ie測試以下代碼:


    <form><input id="test" name="file" type="file"></form>
    <script>
    document.getElementById(
    "test").onchange = function(){
        
    this.select(); document.selection.clear();
        
    this.form.submit();
    }
    </script>


    執行到submit會顯示“拒絕訪問”的錯誤,原因不清楚,不知是ie故意的還是bug。

    看來也只能使用方法1了:


    function ResetFile(file){
        file.value 
    = "";//ff chrome safari
        if ( file.value ) {
            
    if ( $$B.ie ) {//ie
                with(file.parentNode.insertBefore(document.createElement('form'), file)){
                    appendChild(file); reset(); removeNode(
    false);
                }
            } 
    else {//opera
                file.type = "text"; file.type = "file";
            }
        }
    }

    ps:有更好方法的話記得告訴我啊。

    這個函數并不夠通用,最好還是根據實際情況選擇需要的方法。


    使用技巧

    【上傳文件數】

    在文件上傳實例中,各個文件是同時上傳的。
    經測試,瀏覽器能同時上傳的文件數如下:
    ie 2
    ff 8
    opera 8
    chrome 6
    safari 6
    由于ie最多同時只能傳2個,所以設置更多文件也只能排隊,而不能達到同時上傳的效果的。
    ps:只是目測結果,有錯請提出。

    【傳遞參數】

    上傳文件實例中,可以傳遞對應的修改文件名,在使用“一般上傳”多個文件一起上傳時也能找到對應的文件名。
    因為表單控件值傳遞到后臺后,獲取數據的順序跟前臺表單控件的排列順序是一致的。
    只要保證前臺file控件跟對應表單控件的排列順序一致就能利用這個特性獲取對應的值了。
    詳細參考后臺代碼。

    【回調函數】

    有兩個方法可以響應上傳完成回調函數。
    一種是后臺上傳完成后,在iframe輸出并執行回調函數或通過parent調用父窗口的回調函數。
    這種比較方便,但必須在iframe里面執行處理,例如文件屬性查看實例。
    另一種是在iframe的onload中執行回調函數。
    好處是可以把所有處理放在父窗口,iframe可以不做任何處理或用來反饋信息。
    缺點是有兼容性問題,而且會有加載后沒有觸發onload的情況(上面的iframe部分有說明)。
    上傳文件實例中就是在onFinish中處理在iframe中輸出的數據。
    由于可能出現一些意外情況導致響應很久,甚至沒有響應,所以一定要設置timeout以防萬一。

    【處理返回數據】

    上面提到,可以在onFinish中處理在iframe中輸出的數據。
    要從iframe的body中獲取數據,有以下幾個方法:
    iframe.contentWindow.document.body.innerHTML
    iframe.contentDocument.body.innerHTML
    window.frames[iframename].document.body.innerHTML
    其中前兩種差不多,后者比較簡便,但ie不支持contentDocument,可惜。
    第三種是利用frames對象來獲取,注意這樣獲取的對象直接就是window對象。
    由于程序能直接獲得iframe對象,所以用的是第一種方式。
    不過有一個問題在iframe的部分也提過,就是返回錯誤信息頁面的問題。
    在上傳文件實例中,在iframe中輸出的是json形式的文件信息數據。
    在onFinish中是這樣處理的:

    try{
        
    var info = eval("(" + iframe.contentWindow.document.body.innerHTML + ")");
        show(
    "上傳完成");
    }
    catch(e){
        show(
    "上傳失敗"); stop(); return;
    }

    只有返回正確的json格式數據才能正常運行,否則就拋出錯誤,間接地排除了404等錯誤信息。
    ps:有更好方法的話歡迎提出。

    【銷毀程序】

    程序中有不少dom操作,在不需要繼續使用的時候最好執行一次dispose方法來銷毀程序。
    例如移除file之后,關閉窗口之前,提交表單之前,歷遍表單元素前等等。
    既可以節省資源,防止dom的內存泄漏,又能避免表單嵌套時的沖突問題。

    【可用性】

    看過“ppk談javascript”后,更加注重了可用性。
    上傳實例在瀏覽器不支持js的情況下也能正常上傳,各位可以自行測試。

    【編碼】

    上一個無刷新上傳系統,很多人反映上傳后文件名亂碼,后來發現是編碼的問題。
    當有中文信息傳遞時,要注意前后臺的編碼必須統一,包括charset,文件編碼,web.config的配置等。

    【asp版本】

    asp版本跟.net版本功能是一樣的,使用無組件上傳類。
    不過上傳類本身有一個缺陷導致提交同名file控件的話會出錯,經過修改后現在可以正常使用了。


    使用說明

    實例化時,第一個必要參數是file控件對象:

    new QuickUpload(file);


    第二個可選參數用來設置系統的默認屬性,包括
    屬性:    默認值//說明
    parameter: {},//參數對象
    action:  "",//設置action
    timeout: 0,//設置超時(秒為單位)
    onReady: function(){},//上傳準備時執行
    onFinish: function(){},//上傳完成時執行
    onStop:  function(){},//上傳停止時執行
    onTimeout: function(){}//上傳超時時執行

    還提供了以下方法:
    upload:執行上傳操作;
    stop:停止上傳操作;
    dispose:銷毀程序。


    程序源碼


    var QuickUpload = function(file, options) {
        
        
    this.file = $$(file);
        
        
    this._sending = false;//是否正在上傳
        this._timer = null;//定時器
        this._iframe = null;//iframe對象
        this._form = null;//form對象
        this._inputs = {};//input對象
        this._fFINISH = null;//完成執行函數
        
        $$.extend(
    thisthis._setOptions(options));
    };
    QuickUpload._counter 
    = 1;
    QuickUpload.prototype 
    = {
      
    //設置默認屬性
      _setOptions: function(options) {
        
    this.options = {//默認值
            action:        "",//設置action
            timeout:    0,//設置超時(秒為單位)
            parameter:    {},//參數對象
            onReady:    function(){},//上傳準備時執行
            onFinish:    function(){},//上傳完成時執行
            onStop:        function(){},//上傳停止時執行
            onTimeout:    function(){}//上傳超時時執行
        };
        
    return $$.extend(this.options, options || {});
      },
      
    //上傳文件
      upload: function() {
        
    //停止上一次上傳
        this.stop();
        
    //沒有文件返回
        if ( !this.file || !this.file.value ) return;
        
    //可能在onReady中修改相關屬性所以放前面
        this.onReady();
        
    //設置iframe,form和表單控件
        this._setIframe();
        
    this._setForm();
        
    this._setInput();
        
    //設置超時
        if ( this.timeout > 0 ) {
            
    this._timer = setTimeout( $$F.bind(this._timeout, this), this.timeout * 1000 );
        }
        
    //開始上傳
        this._form.submit();
        
    this._sending = true;
      },
      
    //設置iframe
      _setIframe: function() {
        
    if ( !this._iframe ) {
            
    //創建iframe
            var iframename = "QUICKUPLOAD_" + QuickUpload._counter++,
                iframe 
    = document.createElement( $$B.ie ? "<iframe name=\"" + iframename + "\">" : "iframe");
            iframe.name 
    = iframename;
            iframe.style.display 
    = "none";
            
    //記錄完成程序方便移除
            var finish = this._fFINISH = $$F.bind(this._finish, this);
            
    //iframe加載完后執行完成程序
            if ( $$B.ie ) {
                iframe.attachEvent( 
    "onload", finish );
            } 
    else {
                iframe.onload 
    = $$B.opera ? function(){ this.onload = finish; } : finish;
            }
            
    //插入body
            var body = document.body; body.insertBefore( iframe, body.childNodes[0] );
            
            
    this._iframe = iframe;
        }
      },
      
    //設置form
      _setForm: function() {
        
    if ( !this._form ) {
            
    var form = document.createElement('form'), file = this.file;
            
    //設置屬性
            $$.extend(form, {
                target: 
    this._iframe.name, method: "post", encoding: "multipart/form-data"
            });
            
    //設置樣式
            $$D.setStyle(form, {
                padding: 
    0, margin: 0, border: 0,
                backgroundColor: 
    "transparent", display: "inline"
            });
            
    //提交前去掉form
            file.form && $$E.addEvent(file.form, "submit", $$F.bind(this.dispose, this));
            
    //插入form
            file.parentNode.insertBefore(form, file).appendChild(file);
            
            
    this._form = form;
        }
        
    //action可能會修改
        this._form.action = this.action;
      },
      
    //設置input
      _setInput: function() {
        
    var form = this._form, oldInputs = this._inputs, newInputs = {}, name;
        
    //設置input
        for ( name in this.parameter ) {
            
    var input = form[name];
            
    if ( !input ) {
                
    //如果沒有對應input新建一個
                input = document.createElement("input");
                input.name 
    = name; input.type = "hidden";
                form.appendChild(input);
            }
            input.value 
    = this.parameter[name];
            
    //記錄當前input
            newInputs[name] = input;
            
    //刪除已有記錄
            delete oldInputs[name];
        }
        
    //移除無用input
        for ( name in oldInputs ) { form.removeChild( oldInputs[name] ); }
        
    //保存當前input
        this._inputs = newInputs;
      },
      
    //停止上傳
      stop: function() {
        
    if ( this._sending ) {
            
    this._sending = false;
            clearTimeout(
    this._timer);
            
    //重置iframe
            if ( $$B.opera ) {//opera通過設置src會有問題
                this._removeIframe();
            } 
    else {
                
    this._iframe.src = "";
            }
            
    this.onStop();
        }
      },
      
    //銷毀程序
      dispose: function() {
        
    this._sending = false;
        clearTimeout(
    this._timer);
        
    //清除iframe
        if ( $$B.firefox ) {
            setTimeout($$F.bind(
    this._removeIframe, this), 0);
        } 
    else {
            
    this._removeIframe();
        }
        
    //清除form
        this._removeForm();
        
    //清除dom關聯
        this._inputs = this._fFINISH = this.file = null;
      },
      
    //清除iframe
      _removeIframe: function() {
        
    if ( this._iframe ) {
            
    var iframe = this._iframe;
            $$B.ie 
    ? iframe.detachEvent( "onload"this._fFINISH ) : ( iframe.onload = null );
            document.body.removeChild(iframe); 
    this._iframe = null;
        }
      },
      
    //清除form
      _removeForm: function() {
        
    if ( this._form ) {
            
    var form = this._form, parent = form.parentNode;
            
    if ( parent ) {
                parent.insertBefore(
    this.file, form); parent.removeChild(form);
            }
            
    this._form = this._inputs = null;
        }
      },
      
    //超時函數
      _timeout: function() {
        
    if ( this._sending ) { this._sending = falsethis.stop(); this.onTimeout(); }
      },
      
    //完成函數
      _finish: function() {
        
    if ( this._sending ) { this._sending = falsethis.onFinish(this._iframe); }
      }
    }

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 黄又色又污又爽又高潮动态图 | 欧美另类图区清纯亚洲| 成人无码特黄特黄AV片在线| 国产成人亚洲精品无码青APP| 国产成人无码A区在线观看视频| 精品国产成人国产在线观看| 2020国产激情视频在线观看| 在线观看成人年视频免费| 国自产偷精品不卡在线| 再深点灬舒服灬太大了少妇| 久久96热在精品国产高清| 国产亚洲精品AA片在线播放天| 亚洲AV无码乱码国产麻豆| 亚洲乱码中文字幕小综合| 亚洲男人AV天堂午夜在| 东方四虎av在线观看| 深夜国产成人福利在线观看| 亚洲人成网线在线播放VA| 再深点灬舒服灬太大了少妇| 狠狠做五月深爱婷婷伊人| 亚洲第一极品精品无码久久| 国产亚洲999精品AA片在线爽| 极品尤物被啪到呻吟喷水| 成人无码视频在线观看免费播放| 波多野结AV衣东京热无码专区| 国产片AV国语在线观看手机版| 99久久99久久精品国产片 | 黑巨茎大战俄罗斯美女 | 日本公妇被公侵犯中文字幕| 亚洲国产精品一二三区| 99久久精品国产综合一区| 人人妻人人澡人人爽欧美一区 | 国产亚洲精AA在线观看SEE| 久久久亚洲欧洲日产国码农村| 欧美肥老太牲交大战| 无码激情亚洲一区| 亚洲男女羞羞无遮挡久久丫| 午夜通通国产精品福利| 免费a级毛片无码av| 成A人片亚洲日本久久| 六月丁香婷婷色狠狠久久|