Python Automation Development Learning 24-django (AJAX)

Source: Internet
Author: User

Lecturer's blog address: http://www.cnblogs.com/wupeiqi/articles/5703697.html. Known as the Ajax set

Native Ajax

Ajax is primarily the use of XMLHttpRequest objects to complete the requested operation, which exists in the mainstream browser (except for the earlier IE). Syntax for creating XMLHttpRequest objects:

xmlhttp=new XMLHttpRequest();

Older versions of Internet Explorer (IE5 and IE6) use ActiveX objects:

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
Main methods of XMLHttpRequest objects

Once you have created the object, you can invoke the following methods through the object:

    • void Open (String method,string url,boolen async): Create request
      • Method: The requested way, such as: POST, GET, DELETE, etc.
      • URL: The requested address
      • Async: Is async. is generally asynchronous, but he also supports the use of synchronization
    • void Send (String body): Send request
      • Body: The data to be sent
    • void setRequestHeader (String header,string value): Sets the request header
      • Header: The key of the request header
      • Value: The value of the request header
    • String getallresponseheaders (): Gets all response headers, the return value is the response header data
    • String getResponseHeader (string header): Gets the value of the header specified in the response header
      • Header: The key of the response header, the return value is the value of the response header
    • void Abort (): Terminate request
Send a request using native methods

Send a GET request
Using the method above, send an empty GET request first:

<!-- ajax.html 文件 --><body><input type="text" placeholder="随便写点值,看看页面是否有刷新"><input type="button" value="Ajax" /><script>    document.getElementsByTagName(‘input‘)[0].onclick = function () {        var xmlhttp = new XMLHttpRequest();        xmlhttp.open(‘GET‘, ‘/ajax/‘);        xmlhttp.send();    };</script></body>

To be able to actually have a service to respond to this request, you have to write a handler function:

# views.py 文件def ajax(request):    return render(request, ‘ajax.html‘)

Open the console and click the button on the network to trigger the event to see the request we sent. Click on this request to see the header. There is also the text, the body of the response body returned is the entire page of HTML. And the page is not refreshed throughout the process.

Send a POST request
The above is sent a GET request, if you want to send a POST request, not only to change the method parameter, you must also set the request header:

xmlhttp.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded; charset-UTF-8‘);

In addition, there will be csrf problems, Csrf_token can be placed in the form, but also can be set to the request header.

xmlhttp.setRequestHeader(‘X-CsrfToken‘, "{{ csrf_token }}");

Used to always use {% Csrf_token%}, which is to generate an HTML, using {{Csrf_token}}, which is directly the token string.
In addition, the client's cookie will also have a CSRF value, and the value of {{Csrf_token}} is different, but it can also be verified by CSRF if it is obtained again in the request head:

xmlhttp.setRequestHeader(‘X-CsrfToken‘, getCookie(‘csrftoken‘));// 这里需要一个getCookie方法,有很多的实现方式,比如下面用正则匹配的function getCookie(name) {    var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");    if(arr=document.cookie.match(reg)){        return arr[2];    } else {        return null;    }}
Main properties of the XMLHttpRequest object
    • Number readyState: Status value
      • 0-Uninitialized, the open () method has not been called;
      • 1-started, called the Open () method, did not call the Send () method;
      • 2-Sent, the Send () method has been called, the response has not been received;
      • 3-Received, has received a partial response data;
      • 4-Completed, has received all the response data;
    • Function onreadystatechange: Automatically triggers execution of its corresponding functions when the value of readystate is changed (callback function)
    • String responsetext: Data returned by the server
    • XmlDocument responsexml: Data returned by the server (XML object)
    • Number states: Status code (integer), such as: 200, 404, etc.
    • String Statestext: Status text (string), such as: OK, NotFound, etc., corresponding to the above status code text description

Add a point of knowledge : about the status code and status text, you can also set it back using HttpResponse:

return HttpResponse(json.dumps(ret), status=404, reason="Not Found")

and generally this status code return is often 200, because even if there are errors in the background, we capture or verify processing, and then return to the normal data. If you need to use this status code, return as above with the status parameter to set the state code. Or we don't want this generic status code, but in our own RET dictionary, we also make a set of rules that represent the state information returned by the application. Both uses are used and seem to be doing more.

Issues with compatibility

Solve the problem of compatibility, just need to solve this code is good var xmlhttp = new XMLHttpRequest(); if you have this object, then use this object, if there is no such object, use another object. The following function provides a way to return the correct object:

<script>    function GetXmlhttp(){        var xmlhttp = null;        if(XMLHttpRequest){            xmlhttp = new XMLHttpRequest();        }else{            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");        }        return xmlhttp;    }    // 使用的时候就不是创建对象了,而是通过上面的方法获取到对象    // var xmlhttp = GetXmlhttp();</script>

The effect of the following 3 sentences is the same, is speaking of compatibility when incidentally mentioned. That is, the following 3 ways of referencing are all possible.

The Ajax of JQuery

Native methods help us understand the principle, and the use of jquery is much more convenient.

Parameters of the callback function-Gets the native XMLHttpRequest object

Before using the callback function success, only one parameter was used. This callback function has a maximum of 3 parameters:

    1. If only one parameter is passed, indicating that only the text information of the server response is requested, so that a JSON-formatted text message can be set on the server according to the requirements, and the client can get the data directly to the service side.
    2. If two parameters are passed, a state parameter is added on the basis of the first argument. For example: It will return the string "success", seemingly useless.
    3. If you pass three parameters, the third parameter is the complete AJAX corresponding state information. It is the XMLHttpRequest object, which can be manipulated according to the native method.
      There are examples in the section below to upload files
Pseudo-Ajax requests

Because the IFRAME tag of an HTML tag has an attribute that loads content locally, it can be used to forge an AJAX request.

IFRAME Label

Adding a src attribute inside the tag creates an inline frame with another document inside the element (that is, nesting a Web page):

<body><iframe src="http://blog.51cto.com/steed"></iframe>

It also comes with a method to follow the URL of the input box and refresh the nested pages in the IFRAME tag. However, the overall page is not refreshed, only the inside of the nested frame will change. The problem with the above example is that the IFRAME tag can also be implemented without flushing the page to send the request and get the returned data (secretly send the request).
Next, based on the above, an IFRAME tag is now written in the form, and is associated with the name of the IFRAME by the target property. The form request on the original page is now implemented in the IFRAME without refreshing the page submission and data return:

<form action="/ajax/" method="POST" target="ifm"> {% csrf_token %} <iframe name="ifm"></iframe> <input type="text" name="username" /> <input type="submit" /></form>

The following are the corresponding handler functions:

# views.py 文件import timedef ajax(request): if request.method == ‘GET‘: return render(request, ‘ajax.html‘) elif request.method == ‘POST‘: ret = {‘code‘: True, ‘data‘: request.POST.get(‘username‘)} time.sleep(3) return HttpResponse(json.dumps(ret))
Get return value

Although the above returns a value, it is displayed on the page, how to get the data. Inside the IFRAME is a complete document object, which requires a special method to fetch the value inside. In addition, the IFRAME inside is committed and the return data will only have the value we need, and immediately after the submission is not obtained, you need to wait until the data returned to obtain. The above processing function added a sleep, the effect is better obvious.
Time to get data
When the data of the IFRAME is loaded, an onload event is triggered and a function is bound to the OnLoad event, which is then fetched to get the latest value inside the tag. However, this is not perfect, the first time loading the page will also trigger the OnLoad event, to solve this problem, you need to bind the event to submit, through the submit event to the IFRAME tag binding onload event:

<script>    document.getElementsByTagName(‘form‘)[0].onsubmit = function () {        document.getElementsByTagName(‘iframe‘)[0].onload = function () {            alert(123)        };    }</script>

Ways to get Data
Since the inside of the IFRAME is a DOM object, it .contentWindow.document is the DOM object that is the inner layer. Then is the knowledge of the previous study:

<script>    document.getElementsByTagName(‘form‘)[0].onsubmit = function () {        document.getElementsByTagName(‘iframe‘)[0].onload = function () {            var text = this.contentWindow.document.getElementsByTagName(‘body‘)[0].innerText;            alert(text);        };    }</script>

If you are using jquery, use the jquery method:

<script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script><script>    $(‘form‘).submit(function () {        $(‘iframe‘).load(function () {            var text = $(this).contents().find(‘body‘).text();            alert(text);        })    })</script>
Uploading files

All that was previously sent through Ajax was normal data. When sending ordinary data, it is recommended or jquery, and the second is to use the original, pseudo-Ajax is not convenient.
Below to see the unusual data, is to upload files.

Good-looking upload button

The following input is the system's own upload button:

The upload button looks different in the unused browser, and the style is not completely customized to your needs. If you want to make a good-looking upload button, you need special treatment.

The idea is to overlap the default input with our tags. Put the default input on it, but the transparency is set to 0 and invisible. Our custom-made labels are placed below, but the upper layer is invisible due to full transparency, and the effect we see is the effect of our custom labels. But the effect of the click is to click the Default Input button, because it is the real element in the upper layer, just invisible.
To customize the good-looking upload button, basically is based on this way to achieve.

FormData Object

A Formdata object needs to be introduced here first. The Formdata object is used to compile data into key-value pairs so that data can be sent using XMLHttpRequest. This object has a append () method that adds a key-value pair for the current Formdata object:

void append(String name, String value);void append(String name, Blob value, optional String filename);

The first usage is to pass in 2 strings, preceded by Key, followed by a string.
The second use is that the second parameter passes in a Blob object, a class file object that is immutable, raw data. Simple to understand the file object is good, in the above example, through the var file_obj = document.getElementById(‘file‘).files[0]; can get to this file object.
Finally, there is an optional (optional) third parameter that specifies the file name of the files.

Native Ajax uploads

The Code of the page is as follows, mainly see the JS section:

Corresponding to the back end of the processing function:

# views.py 文件def upload(request): if request.method == ‘GET‘: return render(request, ‘upload.html‘) elif request.method == ‘POST‘: username = request.POST.get(‘username‘) file_obj = request.FILES.get(‘file‘) print(type(file_obj), file_obj) # 从这里看到已经收到文件了 print(file_obj.__dict__) # 看看有哪些属性,比如:文件名、大小、文件类型 ret = {‘code‘: True, ‘data‘: username} # 保存文件 with open(file_obj.name, ‘wb‘) as file: for item in file_obj.chunks(): file.write(item) return HttpResponse(json.dumps(ret))
Ajax uploads for JQuery

Only the JS section and the above are different:

<script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script><script>    $(‘#btn‘).click(function () {        var file_obj = $(‘:file‘)[0].files[0];        var form_data = new FormData();        form_data.append(‘username‘, ‘root‘);        form_data.append(‘file‘, file_obj);        $.ajax({            url: ‘/upload/‘,            type: ‘POST‘,            data: form_data,            headers: {‘X-CsrfToken‘: "{{ csrf_token }}"},            processData: false,  // 上传文件必须要有这句,告诉jQuery不要对data进行加工            contentType: false,  // 上传文件必须要有这句,告诉jQuery不要设置contentType            success: function (data, textStatus, jqXHR) {                console.log(data);                console.log(textStatus);                console.log(jqXHR);            }        })    })</script>
Pseudo-Ajax upload file

Uploading files using Ajax above must depend on the Formdate object. But this object is not supported by all browsers, yes, the old version of IE. To consider compatibility issues, you need to use pseudo-Ajax here.
Using forged Ajax to upload files and upload general content is almost no different, add a type="file" input box.
Note : You need to add enctype="multipart/form-data" this property to the form tag to upload the file.

<form action="/upload/" method="POST" target="ifm" enctype="multipart/form-data">    {% csrf_token %}    <iframe name="ifm"></iframe>    <input type="text" name="username" />    <input type="file" name="file">    <input type="submit" /></form><script src="http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js"></script><script>    $(‘form‘).submit(function () {        $(‘iframe‘).load(function () {            var text = $(this).contents().find(‘body‘).text();            var obj = JSON.parse(text);            console.log(obj);        })    })</script>

There is more than one iframe of the large box, settings style="display: none;" can be. The rest of the Upload button beautification method should be the same.
The compatibility of this method is the highest, so pseudo-Ajax is the recommended method in the application scenario of uploading files.

Generate previews

If the uploaded file is a picture, you can generate a preview. The uploaded image is stored in a static file directory, setting.py also set the static file directory. Like what:

STATICFILES_DIRS = (    os.path.join(BASE_DIR, ‘static‘),)

The picture previewed here is obtained from the server. That is to upload the image of the server, and then the server to return the file on the server path to preview, preview and then through the path to the server-side files, and finally displayed on the page.
The processing function modifies the default is saved to the root directory, and is now saved to the dedicated directory:

# views.py 文件import osdef upload(request):    if request.method == ‘GET‘:        return render(request, ‘upload.html‘)    elif request.method == ‘POST‘:        username = request.POST.get(‘username‘)        file_obj = request.FILES.get(‘file‘)        # print(type(file_obj), file_obj)  # 从这里看到已经收到文件了        # print(file_obj.__dict__)  # 看看有哪些属性,比如:文件名、大小、文件类型        img_path = os.path.join(‘static/imgs/‘, file_obj.name)  # 生成文件保存的路径        ret = {‘code‘: True, ‘data‘: username, ‘img‘: img_path}  # 返回的信息要有文件的路径        # 保存文件        with open(img_path, ‘wb‘) as file:            for item in file_obj.chunks():                file.write(item)        return HttpResponse(json.dumps(ret))

The main change is to generate the path to save the file, and return the path to the client.
Here is the full code for HTML:

 <div id= "preview" ></div><form action= "/upload/" method= "POST" target= "IFM" enctype= "Multipart/form-data" > {% csrf_token%} <iframe name= "IFM" style= "Display:none;" ></iframe> <input type= "text" name= "username"/> <input type= "file" name= "file" > <input t Ype= "Submit"/></form><script src= "Http://lib.sinaapp.com/js/jquery/1.12.4/jquery-1.12.4.min.js" > </script><script> $ (' form '). Submit (function () {$ (' iframe '). Load (function () {var text            = $ (This). Contents (). Find (' body '). Text ();            var obj = json.parse (text);            Console.log (obj);            var Imgtag = document.createelement (' img ');  IMGTAG.SRC = "/" + obj.img;  Note here that you need to add a '/' $ (' #preview ') before. empty ();        There may be a preview of the last time, to empty the $ (' #preview ') first. append (Imgtag); })}) </script>  

A div with a picture preview is preset above. After the AJAX request is returned, get to the picture path (this path should be directly stitched to "127.0.0.1:8000" after the image can be accessed). Create an IMG tag, set SRC, and add it to the preview Div. Before adding it, clear the div because there is an IMG tag that was added in the last preview

One-Step submission

The upload file above is uploaded in two steps, the first is the input[type= ' File ' tab selection file, then the Submit or button binding event to commit.
It is also possible to avoid the following submit or button buttons, binding a onchange event for input[type= ' file ' to trigger a submit event for a form form, or to replace the onclick event with the original button button. The previous implementation simply adds the following event bindings:

<script>    $(‘:file‘).change(function () {        $(‘form‘).submit();    });<script>

Python Automation Development Learning 24-django (AJAX)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.