ajax以及文件上傳的幾種方式

方式一:經過form表單中,html input 標籤的「file」完成

# 前端代碼uoload.html
    <form method="post" action="/upload/" enctype="multipart/form-data">
        <input id="user" type="text" name="user" />
        <input id='img' type="file" name="img" />
        <input type="submit" />
    </form>
# 後端代碼
def upload(request):
    if request.method == 'POST':
        ret = {'status': False, 'data': None, 'error': None}
        try:
            user = request.POST.get('user')
            img = request.FILES.get('img')
            f = open(os.path.join('static', img.name), 'wb')
            for chunk in img.chunks(chunk_size=1024):
                f.write(chunk)
            ret['status'] = True
            ret['data'] = os.path.join('static', img.name)
        except Exception as e:
            ret['error'] = e
        finally:
            f.close()
            return HttpResponse(json.dumps(ret))
    return render(request, 'upload.html')

方法二:利用XmlHttpRequest對象,發送原生的Ajax請求

(這種方法不能發送文件,須要依賴另一個對象FormData)html

# 方法
a. void open(String method,String url,Boolen async)
   用於建立請求
    
   參數:
       method: 請求方式(字符串類型),如:POST、GET、DELETE...
       url:    要請求的地址(字符串類型)
       async:  是否異步(布爾類型)
 
b. void send(String body)
    用於發送請求
 
    參數:
        body: 要發送的數據(字符串類型)
 
c. void setRequestHeader(String header,String value)
    用於設置請求頭
 
    參數:
        header: 請求頭的key(字符串類型)
        vlaue:  請求頭的value(字符串類型)
 
d. String getAllResponseHeaders()
    獲取全部響應頭
 
    返回值:
        響應頭數據(字符串類型)
 
e. String getResponseHeader(String header)
    獲取響應頭中指定header的值
 
    參數:
        header: 響應頭的key(字符串類型)
 
    返回值:
        響應頭中指定的header對應的值
 
f. void abort()
 
    終止請求

# 屬性
a. Number readyState
   狀態值(整數)
 
   詳細:
      0-未初始化,還沒有調用open()方法;
      1-啓動,調用了open()方法,未調用send()方法;
      2-發送,已經調用了send()方法,未接收到響應;
      3-接收,已經接收到部分響應數據;
      4-完成,已經接收到所有響應數據;
 
b. Function onreadystatechange
   當readyState的值改變時自動觸發執行其對應的函數(回調函數)
 
c. String responseText
   服務器返回的數據(字符串類型)
 
d. XmlDocument responseXML
   服務器返回的數據(Xml對象)
 
e. Number states
   狀態碼(整數),如:200、404...
 
f. String statesText
   狀態文本(字符串),如:OK、NotFound...

XmlHttpRequest對象的主要屬性和方法
XmlHttpRequest對象的主要屬性和方法
<input type="button" value="XMLHttpRequest按鈕" onclick="XHRAjax();">
 
<script>
        function XHRAjax() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () { # 回調函數--每當請求變化時,都會被觸發,好比:建立、open、send、recv等。
                if(xhr.readyState == 4){   # 僅當服務器數據所有返回時觸發
                    var data = xhr.responseText;
                    console.log(data)
                }
            };
            // GET請求
            // xhr.open('GET', '/xhr_ajax?p=123');
            // xhr.send();
            // POST請求
            xhr.open('POST', '/xhr_ajax/');  # 這裏的URL必須加斜槓結尾。 發送post請求的時候必須攜帶請求頭
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            // 發送請求
            xhr.send('n1=1;n2=2;');
        };
</script>
def ajax(request):
    import time
    current_time = time.time()
    return render(request, 'ajax.html', {'current_time': current_time})

上述的內容,已經能夠完成原生ajax的發送。 若是須要發送文件,則須要藉助於FormData對象.下邊介紹一下FormData的簡單用法前端

# 前端代碼
 
<input type="button" value="XMLHttpRequest-FormData按鈕" onclick="XHRAjaxForm();">
# 後端代碼: 基於FormData對象發送請求
function XHRAjaxForm() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    var data = xhr.responseText;
                    console.log(data)
                }
            };
            xhr.open('POST', '/xhr_ajax/');
            // 發送請求
            var form = new FormData();  # 建立FormData對象
            form.append('user', 'alex');
            form.append('pwd', '123');
            xhr.send(form);
        };

上面的例子,簡單的介紹了FormData的用法 。下邊的案例介紹如何使用formdate對象來上傳文件jquery

 前端部分
<a onclick="uploadfile1();" style="cursor: pointer; display: inline-block;background-color: aqua">XMLHttpRequet上傳</a>
 
# JS部分
<script>
      function uploadfile1() {
            var form = new FormData();
            form.append('user', document.getElementById('user').value);
 
            var fileobj = document.getElementById('img').files[0];
            form.append('img', fileobj);
 
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    var data = xhr.responseText;
                    console.log(data)
                }
            };
            xhr.open('post', '/upload/', true)
            xhr.send(form);
        }
</script>

方法三:利用JQuery Ajax + FormData進行文件上傳

Jquery轉換爲dom對象:$("#img")[0].files[0];   其中$("#img")是jquery對象, $("#img")[0]是dom對象ajax

<a onclick="uploadFile2();" style="cursor: pointer; display: inline-block;background-color: aqua">JQuery-Ajax上傳</a>
 
<script>
 
        function uploadFile2() {
            var fileobj = $("#img")[0].files[0];
            console.log(fileobj);
            var form = new FormData();
            form.append("img", fileobj);
            form.append("uesr", 'alex');
            $.ajax({
                type: 'POST',
                url: '/upload/',
                data: form,
                processData: false, # 告訴jquery要傳輸data對象
                contentType: false,   # 告訴jquery不須要增長請求頭對於contentType的設置
                success: function (arg) {
                    console.log(arg)
                }
            })
        }
</script>

方法四:基於Iframe 實現僞Ajax 上傳文件

<a onclick="uploadFile3();" style="cursor: pointer; display: inline-block;background-color: aqua">IFrame上傳</a>
 
 
 
<script>
        function uploadFile3() {
            // target 是個name的屬性值,而不是id
            $("#container").find('img').remove();
            document.getElementById("my_iframe").onload = callback;
            document.getElementById('fo').target = 'my_iframe';
            document.getElementById('fo').submit();
        }
        function callback() {
            var t = $('#my_iframe').contents().find('body').text();
            var json_data = JSON.parse(t);
            console.log(json_data);
            if(json_data.status){
                // 上傳成功
                var tag = document.createElement('img');
                tag.src = "/" + json_data.data;
                tag.className = 'img';
                $('#container').append(tag);
 
            }else{
                // 上傳失敗
                console.log(status.error);
            }
 
        }
</script>

不是全部的瀏覽器均可以兼容FormData對象。爲了兼容性,引出iframe 的用法。json

   iframe能夠創建一個通道發送請求,利用iframe局部刷新的特性實現目標。後端

# 前端代碼
<iframe name="my_iframe" style="display: none;" src=""></iframe>
# 這裏使用的是name標籤,和id標籤無關
 
 
<a onclick="uploadFile3();" style="cursor: pointer; display: inline-block;background-color: aqua">IFrame上傳</a>
 
<div id="container"></div>
 
    <script>
        function uploadFile3() {
            // target 是個name的屬性值,而不是id
            $("#container").find('img').remove();
            document.getElementById("my_iframe").onload = callback; # 經過js手動綁定一個事件
            document.getElementById('fo').target = 'my_iframe';   # 這裏target對應的是一個iframe 的name屬性
            document.getElementById('fo').submit();
        }
        function callback() {
            var t = $('#my_iframe').contents().find('body').text();
            var json_data = JSON.parse(t);
            console.log(json_data);
            if(json_data.status){  
                // 上傳成功
                 var tag = document.createElement('img');
                tag.src = "/" + json_data.data;
                tag.className = 'img';
                $('#container').append(tag);
 
            }else{
                // 上傳失敗
                console.log(status.error);
            }
 
        }
 
</script>
相關文章
相關標籤/搜索