• AJAX全套


    1.AJAX实现输入框两个数相加,

    """
    Django settings for s4day79 project.
    
    Generated by 'django-admin startproject' using Django 1.11.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'o)rd6bws8#^4l*#l2*@e+u7so4oi766vqc7yapz5s4l*ylegf('
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    # ALLOWED_HOSTS = []
    ALLOWED_HOSTS = ['*']
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 's4day79.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 's4day79.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.11/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )
    settings.py
    from django.shortcuts import render,HttpResponse,redirect
    
    def index(request):
        return render(request,'index.html')   
    
    def add1(request):
        a1 = int(request.POST.get('i1'))   #POST取值
        a2 = int(request.POST.get('i2'))    #POST取值
        return HttpResponse(a1 + a2)
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>首页</h1>
        <input type="text" id="i1" />
        +
        <input type="text" id="i2" />
        =
        <input type="text" id="i3" />
    
        <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();">
        <input type="button" id="btn2" value="原生Ajax" onclick="add2();">
    
    {#    <form action="/fake_ajax/" target="ifr">#}
    {#        <iframe id="ifr" name="ifr"></iframe>#}
    {#        <input type="text" name="user" />#}
    {#        <a onclick="submitForm();">提交</a>#}
    {#    </form>#}
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function add1() {
                $.ajax({
                    url: '/add1/',
                    type: 'POST',
                    data: {'i1':$('#i1').val(),'i2':$('#i2').val()},
                    success:function (arg) {
                        $('#i3').val(arg);
                    }
                })
            }
            
            function add2() {
    
            }
        </script>
    
    {#    <script>#}
    {#        function submitForm() {#}
    {#            document.getElementById('ifr').onload = loadIframe;#}
    {#            document.getElementById('f1').submit();#}
    {#        }#}
    {#        function loadIframe() {#}
    {#            alert(123);#}
    {#        }#}
    {#    </script>#}
    
    
    </body>
    </html>
    index.html

    XMLHttpRequest使用:

    GET请求

    from django.shortcuts import render,HttpResponse,redirect
    
    def index(request):
        return render(request,'index.html')
    
    def add1(request):
        a1 = int(request.POST.get('i1'))
        a2 = int(request.POST.get('i2'))
        return HttpResponse(a1 + a2)
    
    def add2(request):
        if request.method == "GET":
            import time
            time.sleep(10)
            i1 = int(request.GET.get('i1'))
            i2 = int(request.GET.get('i2'))
            print('add2.....')
            return HttpResponse(i1+i2)
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>首页</h1>
        <input type="text" id="i1" />
        +
        <input type="text" id="i2" />
        =
        <input type="text" id="i3" />
    
        <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();">
        <input type="button" id="btn2" value="原生Ajax" onclick="add2();">
    
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function add1() {
                $.ajax({
                    url: '/add1/',
                    type: 'POST',
                    data: {'i1':$('#i1').val(),'i2':$('#i2').val()},
                    success:function (arg) {
                        $('#i3').val(arg);
                    }
                })
            }
            
            function add2() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                    {# 4-完成,已经接收到全部响应数据;#}
                        alert('执行完成');
                    }
                };
                xhr.open('GET','/add2/?i1=12&i2=20');
                xhr.send();
            }
        </script>
    
    
    </body>
    </html>
    index.html

     

                function add2() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                    {# 4-完成,已经接收到全部响应数据;#}
                        alert(xhr.responseText);  修改成xhr.responseText
                    }
                };
                xhr.open('GET','/add2/?i1=12&i2=20');
                xhr.send();
            }

    弹框:

    POST请求

    from django.shortcuts import render,HttpResponse,redirect
    
    def index(request):
        return render(request,'index.html')
    
    def add1(request):
        a1 = int(request.POST.get('i1'))
        a2 = int(request.POST.get('i2'))
        return HttpResponse(a1 + a2)
    
    def add2(request):
        if request.method == "GET":
            # import time
            # time.sleep(10)
            i1 = int(request.GET.get('i1'))
            i2 = int(request.GET.get('i2'))
            print('add2.....')
            return HttpResponse(i1+i2)
        else:   #POST请求
            print(request.POST)
            return HttpResponse('ok')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>首页</h1>
        <input type="text" id="i1" />
        +
        <input type="text" id="i2" />
        =
        <input type="text" id="i3" />
    
        <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();">
        <input type="button" id="btn2" value="原生Ajax" onclick="add2();">
    
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function add1() {
                $.ajax({
                    url: '/add1/',
                    type: 'POST',
                    data: {'i1':$('#i1').val(),'i2':$('#i2').val()},
                    success:function (arg) {
                        $('#i3').val(arg);
                    }
                })
            }
            
            function add2() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                    {# 4-完成,已经接收到全部响应数据;#}
                        alert(xhr.responseText);
                    }
                };
                xhr.open('POST','/add2/');
                xhr.send('i1=12&i2=20');
            }
        </script>
    
    </body>
    </html>
    index.html

    加POST请求,前端页面必须加请求头:

    from django.shortcuts import render,HttpResponse,redirect
    
    def index(request):
        return render(request,'index.html')
    
    def add1(request):
        a1 = int(request.POST.get('i1'))
        a2 = int(request.POST.get('i2'))
        return HttpResponse(a1 + a2)
    
    def add2(request):
        if request.method == "GET":
            # import time
            # time.sleep(10)
            i1 = int(request.GET.get('i1'))
            i2 = int(request.GET.get('i2'))
            print('add2.....')
            return HttpResponse(i1+i2)
        else:
            print(request.POST)#<QueryDict: {}>
            print(request.body)#请求体: b'i1=12&i2=20'
            return HttpResponse('ok')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>首页</h1>
        <input type="text" id="i1" />
        +
        <input type="text" id="i2" />
        =
        <input type="text" id="i3" />
    
        <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();">
        <input type="button" id="btn2" value="原生Ajax" onclick="add2();">
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function add1() {
                $.ajax({
                    url: '/add1/',
                    type: 'POST',
                    data: {'i1':$('#i1').val(),'i2':$('#i2').val()},
                    success:function (arg) {
                        $('#i3').val(arg);
                    }
                })
            }
            
            function add2() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                    {# 4-完成,已经接收到全部响应数据;#}
                        alert(xhr.responseText);
                    }
                };
                xhr.open('POST','/add2/');
                xhr.setRequestHeader('content_type','multipart/form-data'); #添加请求头
                xhr.send('i1=12&i2=20');
            }
        </script>
    
    
    </body>
    </html>
    index.html

     2. 伪Ajax,非XMLHttpRequest

    def autohome(request):
        return render(request,'autohome.html')
    views.py autohome函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <div>
        <input type="text" id="txt1" />
        <input type="button" value="查看" onclick="changeSrc();" />
        <input type="text">
        <input type="text">
        <input type="text">
        <input type="text">
    </div>
        <iframe id="ifr" style=" 1000px;height: 2000px;" src="http://www.autohome.com.cn"></iframe>
    
        <script>
            function changeSrc() {
                var inp = document.getElementById('txt1').value;
                document.getElementById('ifr').src = inp;
            }
        </script>
    
    
    </body>
    </html>
    iframe标签的使用 autohome.html

    用到的技术:
    iframe标签,不刷新发送HTTP请求
    <form>....</form> 把input框里的数据打包,页面刷新

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text" />
        <form method="POST" action="/fake_ajax/" target="ifr">
    target="ifr" 这里相当于form不用原来一提交就刷新的方式了,而改为用iframe提交数据到后台
            <iframe name="ifr"></iframe>
            <input type="text" name="user" />
            <input type="submit" value="提交" />
        </form>
    
    {#<form action="/fake_ajax/" target="ifr">#}
    {#    <iframe id="ifr" name="ifr" style="display: none"></iframe>#}
    {#</form>#}
    
    </body>
    </html>
    fake_ajax.html(伪ajax)

    <form method="POST" action="/fake_ajax/" target="ifr">
    target="ifr" 这里相当于form不用原来一提交就刷新的方式了,而改为用iframe提交数据到后台

     用form+iframe伪造ajax,页面不刷新向后台发起请求

    只要一提交返回数据,但是不刷新,成功伪造了ajax! (页面动了,这是chrome浏览器的特性,IE不会出现这个情况,但是没刷新,因为输入框的数据没有清空) ok是POST请求的返回值。

    前端发数据,后台接收

    def fake_ajax(request):
        if request.method == "GET":
            return render(request,'fake_ajax.html')
        else:
            print('POST')
            print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据
            return HttpResponse('ok')
    fake_ajax
    {#    <input type="text" />#}
        <form method="POST" action="/fake_ajax/" target="ifr">
            <iframe name="ifr" style="display: none"></iframe>
            <input type="text" name="user" />
            <input type="submit" value="提交" />
        </form>
    html页面
    print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据

    
    

     伪AJAX的"回调函数"

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    {#    <input type="text" />#}
        <form method="POST" action="/fake_ajax/" target="ifr">
            <iframe name="ifr" onload="loadIframe();"></iframe>
            <input type="text" name="user" />
            <input type="submit" value="提交" />
        </form>
    
    <script>
        function loadIframe() {
            alert(123);
        }
    </script>
    
    {#<form action="/fake_ajax/" target="ifr">#}
    {#    <iframe id="ifr" name="ifr" style="display: none"></iframe>#}
    {#</form>#}
    
    </body>
    </html>
    fake_ajax.html
    def fake_ajax(request):
        if request.method == "GET":
            return render(request,'fake_ajax.html')
        else:
            print('POST')
            print(request.POST)#<QueryDict: {'user': ['bingabcd']}>拿到提交的数据
            return HttpResponse('返回值')
    views.py fake_ajax函数
    错误信息
    Uncaught ReferenceError: loadIframe is not defined  没有被定义,因为代码从上到下执行
        at HTMLIFrameElement.onload (127.0.0.1/:10)
    <iframe name="ifr" onload="loadIframe();"></iframe>第一次加载到内容,但是js代码在HTML代码下面还没执行,所以会报错。
    <script>
    function loadIframe() {
    alert(123);
    }
    </script>

    解决报错信息:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    {#    <input type="text" />#}
        <form id="f1" method="POST" action="/fake_ajax/" target="ifr">
            <iframe id="ifr" name="ifr"></iframe>
    {#        <iframe name="ifr" onload="loadIframe();"></iframe>#}
            <input type="text" name="user" />
    {#        <input type="submit" value="提交" />#}
            <a onclick="submitForm();">提交</a>
        </form>
    
    <script>
        function submitForm() {
            document.getElementById('f1').submit();
            document.getElementById('ifr').onload = loadIframe;
        }
        function loadIframe() {
            alert(123);
        }
    </script>
    
    {#<form action="/fake_ajax/" target="ifr">#}
    {#    <iframe id="ifr" name="ifr" style="display: none"></iframe>#}
    {#</form>#}
    
    </body>
    </html>
    fake_ajax改进
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="f1" method="POST" action="/fake_ajax/" target="ifr">
            <iframe id="ifr" name="ifr"></iframe>
            <input type="text" name="user" />
            <a onclick="submitForm();">提交</a>
        </form>
    
    <script>
        function submitForm() {
            document.getElementById('ifr').onload = loadIframe;
            document.getElementById('f1').submit();
    先给iframe标签 绑定回调函数,ifram负责给form提交数据,HTML代码从上到下执行,如果绑定的回调函数和绑定提交的函数没执行,上面的代码都不会执行,所以页面不会报错了
    (先绑定再提交)
        }
        function loadIframe() {
            alert(123);
        }
    </script>
    
    
    </body>
    </html>
    fake_ajax.html第二次改进

    先给iframe标签 绑定回调函数,ifram负责给form提交数据,HTML代码从上到下执行,如果绑定的回调函数和绑定提交的函数没执行,上面的代码都不会执行,所以页面不会报错了
    (先绑定再提交)

      

    提交时 先弹出框,再出现返回值

     基于Iframe和Form表单实现伪Ajax操作

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="f1" method="POST" action="/fake_ajax/" target="ifr">
            <iframe id="ifr" name="ifr"></iframe>
            <input type="text" name="user" />
            <a onclick="submitForm();">提交</a>
        </form>
    
    <script>
        function submitForm() {
            document.getElementById('ifr').onload = loadIframe;
            document.getElementById('f1').submit();
        }
        function loadIframe() {
            document.getElementById('ifr')
        }
    </script>
    
    
    </body>
    </html>
    fake_ajax前端代码

    document.getElementById('ifr')加上参数取不到值,因为HTML标签里面还嵌套了HTML标签(页面)

    document.getElementById('ifr').contentWindow
    Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}

    document.getElementById('ifr').contentWindow.document.body这样才能拿到值
    <body>​返回值​</body>​

    document.getElementById('ifr').contentWindow.document.body.innerText
    "返回值"

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="f1" method="POST" action="/fake_ajax/" target="ifr">
            <iframe id="ifr" name="ifr" style="display: none"></iframe>
            <input type="text" name="user" />
            <a onclick="submitForm();">提交</a>
        </form>
    
    <script>
        function submitForm() {
            document.getElementById('ifr').onload = loadIframe;
            document.getElementById('f1').submit();
        }
        function loadIframe() {
    {#        document.getElementById('ifr')#}
            var content = document.getElementById('ifr').contentWindow.document.body.innerText;
            alert(content)
        }
    </script>
    
    </body>
    </html>
    fake_ajax改进版二

     文件上传之原生Ajax

    基于Ajax上传文件:
    1. XMLHttpRequest
    - 原生: 依赖FormData对象(HTML5)
    - jQuery: 依赖FormData对象(HTML5)
    2. 伪造Ajax
    - 兼容性更好

    1.原生Ajax实现文件上传,依赖FormData对象(HTML5)

    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
    #<QueryDict: {'------WebKitFormBoundarymlADIkJ01jWM7uaR
    Content-Disposition: form-data': [''], ' name': ['"k1"
    
    v1
    ------WebKitFormBoundarymlADIkJ01jWM7uaR--
    ']}> <MultiValueDict: {}>
    
            return HttpResponse('OK')
    upload函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
    {#    <div id="container1"></div>#}
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        alert(xhr.responseText);
                    }
                };
                xhr.open('POST','/upload/');
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send(formData);
            }
        </script>
    </body>
    </html>
    upload.html

    #输出值:(加上请求头 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); )

    <QueryDict: {'------WebKitFormBoundary04DkByF1aCOP18ES Content-Disposition: form-data': [''], ' name': ['"k1" v1 ------WebKitFormBoundary04DkByF1aCOP18ES-- ']}> <MultiValueDict: {}>

    输出值:(不加请求头)

    <QueryDict: {'k1': ['v1']}> <MultiValueDict: {}> 输出原来的值

    拿到文件对象:

    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
            return HttpResponse('OK')
    upload函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
    {#    <div id="container1"></div>#}
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                formData.append('fafafa',document.getElementById('i1').files[0]);
                {#    document.getElementById('i1').files[0]既有普通的文本又有普通文件        #}
    {#            //文件对象#}
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        alert(xhr.responseText);
                    }
                };
                xhr.open('POST','/upload/');
    {#            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#}
                xhr.send(formData);
            }
        </script>
    </body>
    </html>
    upload.html

    输出:<QueryDict: {'k1': ['v1']}> <MultiValueDict: {'fafafa': [<InMemoryUploadedFile: QQ图片20170218234431.jpg (image/jpeg)>]}>

    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
            file_obj = request.FILES.get('fafafa')
            file_path = os.path.join("static",file_obj.name)#找到文件
            with open(file_path,'wb') as f:#打开文件
                for chunk in file_obj.chunks():
                    f.write(chunk)#写文件,上传成功
            return HttpResponse(file_path)
    upload函数改版
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
    {#    <div id="container1"></div>#}
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                formData.append('fafafa',document.getElementById('i1').files[0]);
                {#    document.getElementById('i1').files[0]既有普通的文本又有普通文件        #}
    {#            //文件对象#}
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        alert(file_path);
                        {#         responseText拿到文件路径           #}
                    }
                };
                xhr.open('POST','/upload/');
    {#            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#}
                xhr.send(formData);
            }
        </script>
    </body>
    </html>
    upload.html改版

     

     

    http://127.0.0.1:8001/static/QQ%E5%9B%BE%E7%89%8720170218234431.jpg 预览文件

     通过原生ajax发到后台,但是上传文件需要依赖FormData对象

    import os
    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
            file_obj = request.FILES.get('fafafa')
            file_path = os.path.join("static",file_obj.name)#找到文件
            with open(file_path,'wb') as f:#打开文件
                for chunk in file_obj.chunks():
                    f.write(chunk)#写文件,上传成功
            return HttpResponse(file_path)
    upload函数改进
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
        <div id="container1"></div>
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                formData.append('fafafa',document.getElementById('i1').files[0]);
                {#    document.getElementById('i1').files[0]既有普通的文本又有普通文件        #}
    {#            //文件对象#}
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        alert(file_path);
                        var tag = document.createElement('img');
                        tag.src = "/" + file_path;  字符串拼接
                        document.getElementById('container1').appendChild(tag);
                        {#         responseText拿到文件路径           #}
                    }
                };
                xhr.open('POST','/upload/');
    {#            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#}
                xhr.send(formData);
            }
        </script>
    </body>
    </html>
    upload.html上传文件依赖FormData对象

    2.jQuery ajax实现文件上传,依赖FormData对象(HTML5)

    print(request.POST,request.FILES)  <QueryDict: {'k1': ['v1']}> <MultiValueDict: {'fafafa': [<InMemoryUploadedFile: CMDB.jpg (image/jpeg)>]}>
    import os
    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
            file_obj = request.FILES.get('fafafa')
            file_path = os.path.join("static",file_obj.name)#找到文件
            with open(file_path,'wb') as f:#打开文件
                for chunk in file_obj.chunks():
                    f.write(chunk)#写文件,上传成功
            return HttpResponse(file_path)
    upload函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
        <div id="container1"></div>
    
        <h1>jQuery Ajax上传文件</h1>
        <input type="file" id="i2">
        <a onclick="upload2();">上传</a>
        <div id="container2"></div>
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                formData.append('fafafa',document.getElementById('i1').files[0]);
                {#    document.getElementById('i1').files[0]既有普通的文本又有普通文件        #}
    {#            //文件对象#}
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        alert(file_path);
                        var tag = document.createElement('img');
                        tag.src = "/" + file_path;
                        document.getElementById('container1').appendChild(tag);
                        {#         responseText拿到文件路径           #}
                    }
                };
                xhr.open('POST','/upload/');
    {#            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#}
                xhr.send(formData);
            }
            
            function upload2() {
                var formData = new FormData();
                formData.append('k1','v1');
    {#            formData.append('fafafa',document.getElementById('i1').files[0]);#}
                formData.append('fafafa',$('#i2')[0].files[0]);
    {#            $('#i2') -> $('#2')[0]  jQuery对象转成DOM对象    #}
    {#            $(document.getElementById('i1'))    DOM对象转成jQuery对象  #}
                $.ajax({
                    url: '/upload/',
                    type: 'POST',
                    data: formData,
                    contentType:false,
                    processData:false,
                    success:function (arg) {
                        var tag = document.createElement('img');
                        tag.src = "/" + arg;
                        $('#container2').append(tag);
                    }
                })
            }
        </script>
    </body>
    </html>
    upload.html改版
    $('#i2') -> $('#2')[0]  jQuery对象转成DOM对象    
    $(document.getElementById('i1'))    DOM对象转成jQuery对象

    3.伪ajax实现文件上传,兼容性更好

    包含两个元素(iframe和Form)

    切记:上传一定要在Form表单添加 enctype="multipart/form-data"

    import os
    def upload(request):
        if request.method == "GET":
            return render(request,'upload.html')
        else:
            print(request.POST,request.FILES)
            file_obj = request.FILES.get('fafafa')
            file_path = os.path.join("static",file_obj.name)#找到文件
            with open(file_path,'wb') as f:#打开文件
                for chunk in file_obj.chunks():
                    f.write(chunk)#写文件,上传成功
            return HttpResponse(file_path)  返回文件
    upload函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传</a>
        <div id="container1"></div>
    
        <h1>jQuery Ajax上传文件</h1>
        <input type="file" id="i2">
        <a onclick="upload2();">上传</a>
        <div id="container2"></div>
    
        <h1>伪Ajax上传文件</h1>
        <form id="f1" method="POST" action="/upload/" target="ifr" enctype="multipart/form-data">
            <iframe id="ifr" name="ifr" style="display: none"></iframe>
            <input type="file" name="fafafa" />
            <a onclick="upload3();">上传</a>
        </form>
    {#    <a onclick="upload3();">上传</a>#}
        <div id="container3"></div>
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1','v1');
                formData.append('fafafa',document.getElementById('i1').files[0]);
                {#    document.getElementById('i1').files[0]既有普通的文本又有普通文件        #}
    {#            //文件对象#}
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4){
                        var file_path = xhr.responseText;
                        alert(file_path);
                        var tag = document.createElement('img');
                        tag.src = "/" + file_path;
                        document.getElementById('container1').appendChild(tag);
                        {#         responseText拿到文件路径           #}
                    }
                };
                xhr.open('POST','/upload/');
    {#            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');#}
                xhr.send(formData);
            }
            
            function upload2() {
                var formData = new FormData();
                formData.append('k1','v1');
    {#            formData.append('fafafa',document.getElementById('i1').files[0]);#}
                formData.append('fafafa',$('#i2')[0].files[0]);
    {#            $('#i2') -> $('#2')[0]  jQuery对象转成DOM对象    #}
    {#            $(document.getElementById('i1'))    DOM对象转成jQuery对象  #}
                $.ajax({
                    url: '/upload/',
                    type: 'POST',
                    data: formData,
                    contentType:false,
                    processData:false,
                    success:function (arg) {
                        var tag = document.createElement('img');
                        tag.src = "/" + arg;
                        $('#container2').append(tag);
                    }
                })
            }
    
            function upload3() {
                document.getElementById('ifr').onload = loadIframe;
                document.getElementById('f1').submit();
            }
            function loadIframe() {
                var content = document.getElementById('ifr').contentWindow.document.body.innerText;
                var tag = document.createElement('img');
                tag.src = "/" + content;
                $('#container3').append(tag);
            }
        </script>
    </body>
    </html>
    upload.html

    总结:
    1. 用ajax上传文件
      伪造的 ajax,因为兼容性更好
    2. 发数据(字符串,列表,字典)
      - jQuery ajax,写起来更简单,取值更加方便,用 .serialize()取到所有的值.

      -如果不用jQuery ajax,可以用 XMLHttpRequest(伪造),但是代码相对多一点。

    <iframe id="uploadIframe" name="uploadIframe" scrolling="no" height="0px" frameborder="0" 
    style="display:none" src="/blank.html"></iframe>    
    #document == $0
    <html>
        <head>
            <script type="text/javascript">document.domain='chouti.com'</script>
        </head>
        <body>
        {"result":
            {"code":"9999", "message":"图片上传成功",
        "data":
                {"imgUrl":"http://img2.chouti.com/CHOUTI_975BF40BB28440DBA4827DFD6B375075_W1366H768=420x185.jpg",
        "identifie":"1499528915973"
                }
            }
        }
        </body>
    </html>    
    抽屉网上传示例(用的iframe)

    上传图片iframe,有个返回值

    3. 不要被好看的上传按钮迷惑

    <input type="file" name="imgUrl" id="imgUrl" size="1" hidefocus="true">
    #adUploadImgUrl, #imgUrl {
        border: 0;
        filter: alpha(opacity=0);
        background: 0 0;
        opacity: 0;   #当opacity大于0时会出现一个选择框
        -moz-opacity: 0;
         62px;
        height: 31px;
        left: 5px;
        top: 5px9;
        position: absolute;
        cursor: pointer;
    }
    抽屉网上传按钮示例

    宽度大一点,高度大一点,放在标签大一点,透明度等于0,点开上传,其实都是点的里面那个按钮
    position
    z-index

    JSONP

    def jsonp(request):
        return render(request,'jsonp.html')
    jsonp函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <a onclick="sendMsg();">发送</a>
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            function sendMsg() {
                $.ajax({
                    url: 'http://dig.chouti.com/',  #抽屉网
                    type: "GET",
                    success: function (arg) {
                        console.log(arg);
                    }
                })
            }
        </script>
    
    
    
    </body>
    </html>
    jsonp.html
    XMLHttpRequest cannot load http://dig.chouti.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8001' 
    is therefore not allowed access.

    在浏览器上向别的网址发一个请求,  为什么浏览器禁止了,因为浏览器基于同源策略(请求发过去了,但是没有拿到返回值,由于浏览器的同源策略)

    浏览器:同源策略,
    - 禁止:Ajax跨域发送请求时,再回来时浏览器拒绝接收
    - 允许:script标签没禁止(允许src属性)

    不能往别的网址发请求,只能往自己URL发请求  

    解决这个问题的途径就是JSONP,,通过钻空子, 跳过浏览器的同源策略,

    一点发送,head里面就多了一条script数据

          

     script生成的页面会下载到内存里

    function f1(arg) {
        alert(arg)
    }
    commons.js
    f1(123)
    commons2.js
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="/static/commons.js"></script>
        <script src="/static/commons2.js"></script>
    </head>
    <body>
    
        <a onclick="sendMsg();">发送</a>
    {#    <script src="/static/jquery-3.2.1.js"></script>#}
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    
        <script>
            function sendMsg(){
                var tag = document.createElement('script');
                tag.src = "http://www.baidu.com";
                document.head.appendChild(tag);
            }
    
        </script>
    
    
    
    </body>
    </html>
    jsonp.html

    访问http://127.0.0.1:8001/jsonp/即弹出窗口

     

    因为script已经加载到内存,然后commons2.js里执行commons.js里的函数.

    function list(arg) {
        alert(arg)
    }
    commons.js改成list函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="/static/commons.js"></script>
    
    {#    <script src="/static/commons2.js"></script>#}
    </head>
    <body>
    
        <a onclick="sendMsg();">发送</a>
    {#    <script src="/static/jquery-3.2.1.js"></script>#}
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    
        <script>
            function sendMsg(){
                var tag = document.createElement('script');
                tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403";
                document.head.appendChild(tag);
            }
    
        </script>
    
    </body>
    </html>
    jsonp.html

    tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403";  相当于生成一个

    <script src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"> </script>

     拿到网页对象了

    如果把commons.js改一下内容,然后拿到所有的数据(发一个请求)

    JSONP规则:跨域。JSONP的本质是可以远程发请求(没用ajax,完成跨域),然后返回数据.

    1.提前定义一个函数

    function list(arg){
    console.log(arg);
    }

    2. 发送端(发送请求,调用上面的list函数,list函数传什么值,上面的函数都能接收到):
    把数据拼接成script代码,script代码放在html
    <script src='http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'></script>
    list({......})
    createElement('script') 创建一个script标签

    function list(arg) {
        console.log(arg)   #arg是一个字典
    }

    出现一连串的对象

  • 相关阅读:
    Html-Css 从入门到放弃(一)基础知识
    PHP7 学习笔记(十)会话控制
    Redis模块学习笔记(一)RediSearch简单使用
    PHP7 学习笔记(九)phpsize动态编译openssl扩展 (微信公众平台)
    Git与GitHub学习笔记(五)一次提交失败的记录
    PHP7 学习笔记(八)JetBrains PhpStorm 2017.1 x64 MySQL数据库管理工具的使用
    PHP7 学习笔记(七)如何使用zephir编译一个扩展记录
    阿里云(四)Linux 实例常用内核网络参数介绍与常见问题处理
    阿里云(三)安全组
    流媒体技术学习笔记之(十七)FFmpeg 3.3《希尔伯特》-新版本的亮点
  • 原文地址:https://www.cnblogs.com/bingabcd/p/7132697.html
Copyright © 2020-2023  润新知