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="width: 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\r\nContent-Disposition: form-data': [''], ' name': ['"k1"\r\n\r\nv1\r\n------WebKitFormBoundarymlADIkJ01jWM7uaR--\r\n']}> <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\r\nContent-Disposition: form-data': [''], ' name': ['"k1"\r\n\r\nv1\r\n------WebKitFormBoundary04DkByF1aCOP18ES--\r\n']}> <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;
    width: 62px;
    height: 31px;
    left: 5px;
    top: 5px\9;
    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是一个字典
}

出现一连串的对象

posted on 2017-07-07 16:03  bigdata_devops  阅读(325)  评论(0编辑  收藏  举报

导航