python_way day21 Django文件上传Form方式提交,原生Ajax提交字符处啊,Django文件上传之原生Ajax方式、jQuery Ajax方式、iframe方式,Django验证码,抽屉示例,

python_way day21

1、Django文件上传至Form方式

2、原生Ajax文件上传提交表单

  使用原生Ajax好处:不依赖jquery,在发送一个很小的文件或者字符串的时候就可以用原生Ajax直接发送
 

 一、Django文件上传至Form方式

<body>
    <div>
        <form action="/upload/" method="POST" enctype="multipart/form-data">
         <!-- enctype="multipart/form-data" 这个字段上传文件必须写上,不写就传不上去。 -->
            <input type="text" id="user" name="user" />
            <input type="file" name="img">
            <input type="submit" value="提交">
        </form>
    </div>
def upload(request):
    if request.method == "POST":
        user = request.POST.get("user", None)
        img = request.FILES.get("img", None)   #表示用户在前段上传的文件,去获取这个文件
        print(img,type(img),"<--------")  #此时就拿到了文件的对象,但是显示是显示文件名
        f = open(os.path.join('statics', img.name), "wb")     
        for file in img.chunks():
            f.write(file)
        f.close()return render(request,"upload.html")
1、文件名: #img.name文件的名字,这里的作用是存放到本地的名字(打开文件的名字)
2、存放位置:  f = open(os.path.join('statics', img.name), "wb"),这样就把文件放到了statics目录中,并且文件名字和上传名字相同。
倒入文件类型的类,看看里面有什么方法: from django.core.files.uploadedfile import InMemoryUploadedFile

打印内容:

  IMG_8409.JPG 显示获取到的img是文件名字,其实是个文件对象

  <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>

  我们倒入这个对象看看里面有什么方法可以供我们使用

def __init__(self, file, field_name, name, content_type, size, charset, content_type_extra=None):
        super(InMemoryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra)

chunks:将用户给的文件分片传递过来。  
def chunks(self, chunk_size=None):
        self.file.seek(0)
        yield self.read()

属性:name,获取文件名,size大小等等

二、原生Ajax提交表单 

使用原生Ajax好处:不依赖jquery,在发送一个很小的文件或者字符串的时候就可以用原生Ajax直接发送

我们经常使用的jquery中的ajax是调用的浏览器中一个XMLHttpRequrst(),这个对象就有发送ajax的能力

 

XMLHttpRequrst() 这个就是原生的Ajax

1、原生Ajax XmlHttpRequest对象的主要方法:

a. void open(String method,String url,Boolen async)
   用于创建请求 (上传文件的位置,方式)   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()
 
    终止请求 

 注:请求头和请求内容中间会隔两个换行

 

2、XmlHttpRequest对象的主要属性:

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...  

 使用示例:

get形式发送

function UploadFile() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {     // onreadystatechange 这个函数在传送信息每次状态发生改变时就会被触发,状态一共有4种:
                if(xhr.readyState == 4){
                    var data = xhr.responseText;    //获取服务器端响应的内容
                    console.log(data);
                }
            };
            xhr.open("post", '/upload/', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');    #设置请求头
            xhr.send("k1=v1;k2=v2");
            //如果要是发送POST请求,就要设置请求头
        }
基础的原生post请求
function UploadFile() {
            var form = new FormData();
            form.append("user","alex");
            form.append("pwd","123");
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {     // onreadystatechange 这个函数在传送信息每次状态发生改变时就会被触发,状态一共有4种:
                if(xhr.readyState == 4){
                    var data = xhr.responseText;    //获取服务器端响应的内容
                    console.log(data);
                }
            };
            xhr.open("post", '/upload/', true);
            //使用formdata对象发送时就不用设置请求头。
            xhr.send(form);
        }
原生ajax使用formdata发送字符串

formdata包含了上面发送字符串的功能,也含有发送文件的功能。

function UploadFile(){
            var fileObj = $('#img')[0].files[0];   //使用ajax获取id为img对象使用[0]转换为dom对象,然后获取files对象
            var form = new FormData();
            form.append('img',fileObj);
            form.append('user','alex');
            $.ajax({
                type:'POST',
                url:'/upload/',
                data: form,  //发送form对象的时候就不需要ajax内部设置请求头
                processData: false,  //告诉jquery不要处理数据
                contentType: false,   //告诉jquery不要在请求头中设置获取发送的内容
                success : function (arg) {
                    console.log(arg)
                }
            })
        }
原生ajax使用formdata对象发送文件
<div>
      <input type="text" id="user" name="user" />
      <input type="file" id="img" name="img" onchange="UploadFile2();">
      <a href="javascript:void(0)" onclick="UploadFile1();">jquery点击上传</a>
</div>
<script src="/statics/jquery-3.1.0.min.js"></script>
<script>
function UploadFile1(){
            var fileObj = $('#img')[0].files[0];   //使用ajax获取id为img对象使用[0]转换为dom对象,然后获取files对象
            var form = new FormData();
            form.append('img',fileObj);
            form.append('user','alex');
            $.ajax({
                type:'POST',
                url:'/upload/',
                data: form,  //发送form对象的时候就不需要ajax内部设置请求头
                processData: false,  //告诉jquery不要处理数据
                contentType: false,   //告诉jquery不要在请求头中设置获取发送的内容
                success : function (arg) {
                    console.log(arg)
                }
            })
        }
<script />
使用jquery发送文件,还是需要formdata

有些阅览器不支持formdata对象,就不能所以就需要使用iframe伪ajax请求

iframe原来的作用:直接可以把别人的页面嵌套在标签内。

iframe的格式是一个新的doc

def upload_ifream(request):
    if request.method == "POST":
        ret = {"status":False, "data":None, "error":None}
        try:
            user = request.POST.get("user", None)
            img = request.FILES.get("img", None)
            print(img)
            file_path = os.path.join("statics", img.name)
            f = open(file_path, "wb")
            for file in img.chunks():
                f.write(file)
            f.close()
            ret["status"] = True
            ret["data"] = file_path
        except Exception as e:
            ret["error"] = str(e)
        return HttpResponse(json.dumps(ret))
    return render(request,"upload.html")
views.py
<style>   //样式:为图片预览展示规定大小
.img {
300px;
height: 500px;
}
</style>
<body>
    <div>
        <iframe id="iframe" name="my_iframe" style="display: none;"></iframe>
        <form action="/upload_ifream/" id="fo" method="POST" enctype="multipart/form-data">
            <!-- enctype="multipart/form-data" 这个字段上传文件必须写上,不写就传不上去。 -->
            <input type="text" id="user" name="user" />
            <input type="file" id="img" name="img" onchange="UploadFile2();">
        </form>
        <div id="container"></div>   //这里是用来做图片预览展示的。
    
    </div>
    <script src="/statics/jquery-3.1.0.min.js"></script>
    <script>
      
    function UploadFile2(){
       $(container).find('img').remove();             //删除原来上传的图片。
  document.getElementById('iframe').onload = callback; // 找到iframe标签 绑定一个加载事件。上传成功后执行callback函数
  document.getElementById('fo').target = "my_iframe"; //找到id为fo的form标签把他提交的路径指向name为my_iframe的iframe标签
  document.getElementById('fo').submit();        //通过js提交表单
    }
  function callback() {
  var text = $("#iframe").contents().find('body').text();//因为iframe中嵌套了一个html页面,所以找他的子孙的时候需要加上contents这个方法
  var json_data = JSON.parse(text); //获取json_data服务器返回的内容。并且注明是json格式
  if(json_data.status){
  //已经上传成功
   var tag = document.createElement('img');//创建img标签
  tag.src = "/" + json_data.data;
  tag.className = "img";
  $("#container").append(tag);
  }else{
  alert(json_data.error)
   }
   }
   </script>
原文地址:https://www.cnblogs.com/python-way/p/5939776.html