二十二 .Django form上传+Ajax+FormData上传+Form组件上传+序列化+ifram伪造Ajax

一. form上传+Ajax+FormData上传+Form组件上传+序列化+ifram伪造Ajax

https://www.cnblogs.com/chris-oil/p/7933060.html HTML5 FormData 方法介绍以及实现文件上传

https://www.cnblogs.com/bigtreei/p/8427108.html     Django 基于Ajax & form 简单实现文件上传

https://www.cnblogs.com/hutuzhu/p/4409292.html   HTML5 FormData实现文件上传实例

1. form表单上传

HTML
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="{%static 'webpage/js/jquery1.js'%}"></script> </head> <body> <form action="{% url "aa" %}" method="post" enctype="multipart/form-data"> {% csrf_token %} <p><input type="text" name="aa"></p> <p><input type="file" name="img"></p> <input type="submit" value="上传"> </form> </body> </html>
VIEWS

from django.shortcuts import render,HttpResponse,render_to_response,redirect
import os
from django.conf import settings

def ajax_show(request):
      if request.method=="GET":
           return  render(request,"01html/04ajax_show.html")
      elif request.method=="POST":
             aa=request.POST.get("aa")
             img = request.FILES.get("img")
             print(img.name)  # 文件呢内容
             print(img.size)  # 文件大小

             f=os.path.join(settings.MDEIA_ROOT,img.name)    # 文件在服务器的路径
             o = open(f, "wb")
             for i in img.chunks():  # chunks()  这个函数表示上传文件一段一段的上传
                   o.write(i)
             o.close()
             return HttpResponse("ok")
print(os.path.join(settings.MDEIA_ROOT))  # J:\orm\02Dorm\webpys\myapp\statics\upfile
print(request.get_full_path()) # /home/ajax_show/
def upload_file(request): 
    if request.method == "POST":    # 请求方法为POST时,进行处理 
        myFile =request.FILES.get("myfile", None)    # 获取上传的文件,如果没有文件,则默认为None 
        if not myFile: 
            returnHttpResponse("no files for upload!") 
        destination = open(os.path.join("E:\\upload",myFile.name),'wb+')    # 打开特定的文件进行二进制的写操作 
        for chunk in myFile.chunks():      # 分块写入文件 
            destination.write(chunk) 
        destination.close() 
        returnHttpResponse("upload over!") 

2 .js+jq+ajax-------url

from django.contrib import admin
from django.urls import path,re_path
from APP.views import Fupload,JAupload,JQupload

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^f_upload.html$',Fupload.F_Upload),
    re_path('^ja_upload.html$',JAupload.JA_Upload),
    re_path('^jq_upload.html$',JQupload.JQ_Upload),
]

3 .jquery+ ajax文件上传

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax upload</title>
    <script src="../static/jquery-3.3.1.min.js"></script>
</head>
<body>


<!--   包含上传文件的必要参数 enctyoe -->
{% csrf_token %}
         <input id="Upfile" type="file"  multiple="multiple" >
         <a id="FileSub">提交</a>

<script>
    $("#FileSub").click(function() {

        var f_obj = $("#Upfile").get(0).files[0];                       //获取上传文件信息
        console.log("文件对象:",f_obj);
        console.log("文件名称是:",f_obj.name);
        console.log("文件大小是:",f_obj.size);

        var data = new FormData();                                      //创建formdata对象,便于将文件传输到后端
        data.append("file",f_obj)                                        //在formdata对象中添加(封装)文件对象

        $.ajax({
            url:'jq_upload.html',
            type:'POST',
            data:data,
            cache: false,                                               //上传文件无需缓存
            processData:false,                                          //不对数据做序列化操作
            contentType:false,                                          //不定义特殊连接类型
            success:function (arg) {
                alert("文件已经上传成功,点击确定刷新页面");
                location.reload();
                                    }
            })
        });
</script>
</body>
</html>


{#processData: false ,    // 不处理数据#}
{#contentType: false, // 不设置内容类型#}


{#processData:#}
{#要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型#}
{# &quot;application/x-www-form-urlencoded&quot;。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false#}


{#contentType: false,#}
{#Query ajax() 方法中我们使contentType = false,这不是冲突了吗?这当然没有,因为当我们查看这时的 Request headers,会发现还是有分界符。#}
{#这就是因为当我们在 form 标签中设置了enctype = “multipart/form-data”,这样请求中的 contentType 就会默认为 multipart/form-data 。#}
{#而我们在 ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。#}
{#说真的,起初我只是想查查为啥使用 ajax 上传文件时要将 contentType = false#}

# -*- coding:utf8 -*-
from django.shortcuts import render,HttpResponse

def JQ_Upload(request):
    if request.method == "GET":
        return render(request,'jquery_ajax_upload.html',)
    else:
        file_obj = request.FILES.get('file')                # 拿到from获取到的file数据
        print("上传文件名称是:", file_obj.name)
        print("上传文件大小是:", file_obj.size)

        f = open('APP/file/' + file_obj.name + "", 'wb')    # 服务器创建上传同名的文件
        for line in file_obj.chunks():                      # 分块拿上传数据
            f.write(line)                                   # 循环写入拿到的数据块到服务器
        f.close()
        return HttpResponse(file_obj.name)

 4 .原生js+ ajax文件上传

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax upload</title>
</head>
<body>

<h1>原生js+原生ajax方式上传提交</h1>
<!--   包含上传文件的必要参数 enctyoe -->
{% csrf_token %}
         <input id="Upfile" type="file"  multiple="multiple" >
         <a onclick="Js_Ajax();">提交</a>

<script>
    function Js_Ajax() {
        var xhr = new XMLHttpRequest();                                                         //创建一个空对象,用于传输后端
        xhr.onreadystatechange = function () {                                                  //指定回调函数
            if (xhr.readyState == 4) {                                                           //回调函数状态判断
                console.log("返回信息:", xhr.responseText);
                alert("文件已经上传成功,点击确定刷新页面");
                location.reload();
            }
        };
        xhr.open('POST', 'ja_upload.html');                                                       //建立POST方式请求
        xhr.setRequestHeader('Conten-Type', 'application/x-www-foorm-urlencoded;charset-UTF-8');  //POST数据请求头

        var f_obj = document.getElementById("Upfile").files[0];                                   //获取上传文件对象
        console.log("文件对象:", f_obj);
        console.log("文件名称是:", f_obj.name);
        console.log("文件大小是:", f_obj.size);

        var data = new FormData();                                                                //创建formdata对象,便于将文件传输到后端
        data.append("file", f_obj);                                                                //在formdata对象中添加(封装)文件对象

        xhr.send(data);                                                                            //建立的POST请求发送的数据
    };
</script>
</body>
</html>
 -*- coding:utf8 -*-
from django.shortcuts import render,HttpResponse

def JA_Upload(request):
    if request.method == "GET":
        return render(request,'js_ajax_upload.html',)
    else:
        file_obj = request.FILES.get('file')                # 拿到from获取到的file数据
        print("上传文件名称是:", file_obj.name)
        print("上传文件大小是:", file_obj.size)

        f = open('APP/file/' + file_obj.name + "", 'wb')    # 服务器创建上传同名的文件
        for line in file_obj.chunks():                      # 分块拿上传数据
            f.write(line)                                   # 循环写入拿到的数据块到服务器
        f.close()
        return HttpResponse('文件上传成功!')

5 .jquery+ ajax文件上传

  

6. Form组件上传

views

1 class F2Form(Form): 2 user=fields.CharField() 3 fafafa=fields.FileField() 4 5 6 def f2(request): 7 if request.method == "GET": 8 obj=F2Form() 9 return render(request,'f2.html',{'obj':obj}) 10 else: 11 obj=F2Form(data=request.POST,files=request.FILES) #以POST的方式获取到文件的所有对象 12 if obj.is_valid(): #校验拿取的文件对象 13 # print(obj.cleaned_data) 14 print(obj.cleaned_data.get('fafafa').name) #校验成功 获取上传文件对象的 fafafa 文件名 15 print(obj.cleaned_data.get('fafafa').size) #获取文件对象的fafafa size大小 16 return render(request,'f2.html',{'obj':obj}) #错误信息的时候 就返回到前端
html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="POST" action="/f2/" enctype="multipart/form-data"> {% csrf_token %} {{ obj.user }} {{ obj.fafafa }} <input type="submit" value="提交"> </form> </body> </html>

 

                    

 

7. Form组件上传+序列化serialize()--(它的操作对象是代表表单元素集合的 jQuery 对)

from django.shortcuts import render, HttpResponse
from django import forms
from django.forms import fields, widgets
import json


# Create your views here.

# views.py

class AjaxForm(forms.Form):
    price = fields.IntegerField()
    user_id = fields.IntegerField(
        widget=(
            widgets.Select(choices=[(0, '张三'), (1, '李四'), (2, '王五'), ])
        )
    )


def ajax(request):
    if request.method == 'GET':
        obj = AjaxForm()
        return render(request, 'ajax.html', {'obj': obj})
    else:
        obj = AjaxForm(request.POST)
        ret = {'status': None, 'message': None}
        if obj.is_valid():
            # print(obj.cleaned_data)
            # return redirect('http://www.baidu.com')  # 使用ajax提交,即使redirect,也不会跳转
            ret['status'] = 'true'
        else:
            # print(obj.errors)  # obj.errors 是一个django.forms.utils.ErrorDict对象,继承自dict(字典)数据类型,默认是ul
            # obj.errors有很多方法 默认为as_ul() 还有 as_json() as_data() as_text()
            ret['message'] = obj.errors.as_text()

            return HttpResponse(json.dumps(ret))      # json.dumps() 只能对python中的基本数据类型进行处理
<!--前端-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form id='fm'>
    <span id="msg"></span>
      {% csrf_token %}
      {{ obj.as_p }}
      <input type='button' value='提交' id='btn'>
</form>

<script src='/static/jquery.js'></script>

<script>
    $(function()
    {
        $('#btn').click(function () {
            $.ajax({
                url: 'http://127.0.0.1:8000',
                type: 'POST',
                dataType: 'JSON',
                data: $('#fm').serialize(),   serialize() 方法通过序列化表单值,创建 URL 编码文本字符串https://www.w3school.com.cn/jquery/ajax_serialize.asp
                success: function (arg) {
                    if (arg.status == 'true') {
                        window.location.href = 'http://www.baidu.com'
                    }else{
                        console.log(arg.message);
                        $("#msg").html(arg.message);
                    }
                }
            })

        })

    })
</script>
</body>
</html>

 

 

 

from django import forms
from django.forms import fields
from django.forms import widgets

class AjaxForms(forms.Form):
   price=fields.IntegerField()
   user_id=fields.IntegerField(
      widget=widgets.Select(choices=[(0,"张杰"),(1,"杨过"),(2,"古龙"),]),  
    )
def ajax_user(request):
  if request.method=="GET":
     obj=AjaxForms()
     return render(request,"html_app/06ajax_user.html",{"obj":obj})
  else:
      ret={"status":"good","message":None}
      import json 
      obj=AjaxForms(request.POST)
      print(obj)
      if obj.is_valid():
          # 成功跳转
          print(obj.cleaned_data)
          # return redirect("http://www.baidu.com")
          ret["status"]=="nice"
          return HttpResponse(json.dumps(ret))

      else:
        # 错误信息显示在页面上
          print(type(obj.errors))
          ret["message"]=obj.errors
          return HttpResponse(json.dumps(ret))



          # <class 'django.forms.utils.ErrorDict'>
 <!DOCTYPE html>
<html>
  <head>

         {%load staticfiles%}
    <meta charset="UTF-8">
    <title>form组件</title>
    <!-- <script type="text/javascript" src="/static/webpage/js/jquery1.js" ></script> -->
     <!-- 引用静态的方式-->
    <script type="text/javascript" src="{%static 'webpage/js/jquery1.js'%}" ></script>  
    
  </head>
  <body>
  <h1>ajax提交form表单组件!!!1</h1>
  <form method="POST" action="/myapp/ajax_user/"  id="fm">
     {%csrf_token%}
     {{obj.as_p}}
     <input type="button" value="ajax提交" id="btn">
  </form>


    <script type="text/javascript">
    $(function () {
       $("#btn").click(function(){
         $.ajax({
           url:"/myapp/ajax_user/",
           type:"POST" ,
           data:$("#fm").serialize(),serialize() 方法通过序列化表单值,创建 URL 编码文本字符串
           dataType:"JSON",
           success:function (arg){
            // args:包含状态  错误信息 
              
              if (arg.status=="good"){
                window.location.href="http://www.baidu.com"
              }
              console.log(arg);
           }    
       });
      });
    });
        
    </script>

 

8. ifram+伪造Ajax

IFRAME是HTML标签,作用是文档中的文档,或者浮动的框架(FRAME)。iframe元素会创建包含另外一个文档的内联框架

ajax的理念是不进行浏览器页面刷新的信息获取更新,也就是局部刷新。

那么伪造ajax的方式即为将向服务端发送请求返回的数据返回到iframe中,再使用js从iframe中的文档中取出数据使用。

 

上面使用Ajax上传文件虽然好,但是仍旧有弊端,因为有的浏览器不支持FormData对象,因此为了更好的兼容性,还是使用表单会好一些,但是别忘了最初寻找Ajax方法上传文件的目的,
因此有没有即能够解决兼容性问题又能够在上传后不刷新页面的方式呢?还真有,那就是使用iframe和表单来伪造Ajax请求,这样既解决了兼容性问题又不会刷新页面。那么究竟如何去做呢?
其实很简单,将form的target属性与iframe的name属性关联即可
 <!DOCTYPE html>
<html>
  <head>

         {%load staticfiles%}
    <meta charset="UTF-8">
    <title>基于iframe +Form </title>
    <!-- <script type="text/javascript" src="/static/webpage/js/jquery1.js" ></script> -->
     <!-- 引用静态的方式-->
    <script type="text/javascript" src="{%static 'webpage/js/jquery1.js'%}" ></script>  
    <style type="text/css">

    </style>
  </head>

   <body>
      <h3>基于iframe +Form // 学习iframe伪ajax!!</h3>
     
 <form action="/myapp/ajax_2/" method="post" target="iframe_1" >
 <iframe style="display: none" id="iframe_1" name="iframe_1" src="" onload="loadIframe();"></iframe>
        <input type="text" name="user" />
        <input type="password" name="pwd" />
        <input type="submit" />
    {% csrf_token %}
</form>
  <script>
// 学习iframe伪ajax!!
    function loadIframe() {
      var str_json = $('#iframe_1').contents().find('body').text();   //找到iframe中的内容
      var obj = JSON.parse(str_json);
   console.log(obj.message)
}
  </script>
   </body>
</html>
import os
from django.conf import settings
from django import forms
from django.forms import fields

import time

def ajax_2(request):
    if request.method == 'GET':
      return render(request,"html_app/02index_ajax.html")
    if req.method=='POST':
        ret = {'message': 'ajax伪造成功'}
        return HttpResponse(json.dumps(ret))

 

  

 https://www.cnblogs.com/Myarticles/articles/9415340.html

 

posted @ 2019-08-18 02:34  supreme999  阅读(258)  评论(0编辑  收藏  举报