A detailed explanation of native JavaScript realizing Ajax processing in jquery _javascript tips

Source: Internet
Author: User
Tags browser cache microsoft edge

In this article, I use Node.js as the backend. Yes, this can be all stack (browser and server) JS. Node.js is very concise, I encourage you to download the demo in GitHub and focus on the project. Here is the server-side code:

App.js
var app = Http.createserver (function (req, res) {
  if (req.url.indexOf ("/scripts/") >= 0) {
    Render (Req.url.slice (1), "Application/javascript", HttpHandler);
  } else if (req.headers[' x-requested-with '] = = ' XMLHttpRequest ') {
    //Send Ajax response
  } else{
    render (' Views/index.html ', ' text/html ', HttpHandler);
  }

The code snippet determines the corresponding content returned by the app by detecting the request URL. If the request is from the scripts directory, the server returns the appropriate file for the content type (the contents types) as Application/javascript. If the x-requested-with of the request head is set to XMLHttpRequest, then the request is an AJAX request, and then the corresponding data is returned. In addition to both of these, the server will return to views/index.html.

I will expand the comments section of the previous code snippet to handle the Ajax request for further explanation. At the node.js end, I have dealt with the physical activity of render and HttpHandler:

App.js
function render (path, ContentType, fn) {
  fs.readfile (__dirname + '/' + path, ' Utf-8 ', function (err, str ) {
    fn (err, str, contentType);
  });
var HttpHandler = function (err, str, contentType) {
  if (err) {
    res.writehead, {' Content-type ': ' Text/plain '} );
    Res.end (' An error has occured: ' + err.message);
  } else {
    Res.writehead {' Content-type ': ContentType});
    Res.end (str);
  }
;


The render function asynchronously reads the contents of the requested file. This function passes a reference to the HttpHandler that is the callback function.
The HttpHandler function detects whether an Error object exists (for example, if the requested file cannot be opened, the object will exist). In addition, specifying a type is a good practice, and the contents of the file returned by the server will have the appropriate HTTP status code (status code) and content type.

Test API
Let's write some unit tests for back-end APIs to make sure they work correctly. For this type of test, I will request SuperTest and Mocha help.

Test/app.request.js
It ("responds with HTML", function (done) {
  request (APP) (
    "/").
    Expect (" Content-type ",/html/)
    . Expect (done);
};
It (' responds with JavaScript ', function (DO) {
request (APP)
  . Get ('/scripts/index.js ')
  . Expect (' Content-type ',/javascript/)
  . Expect (done);
};
It (' responds with JSON ', function (DO) {
request (APP)
  . Get ('/')
  . Set (' X-requested-with ', ' XMLHttpRequest ')
  . Expect (' Content-type ',/json/)
  . Expect (done);

These tests ensure that our app returns the correct content type and HTTP status code (status code) for different requests. Once you have these dependencies installed, you can run the tests using the command NPM test.

Interface
now, let's look at the user interface's HTML code:

views/index.html
 
 

The HTML code above looks very concise. Yes, as you can see, all the exciting things happen in JavaScript.

Onreadystate vs onload
If you have read any authoritative book on Ajax, you may find that onreadystate is ubiquitous in books. The callback function needs to be done through nested IFS or multiple case statements, which makes it difficult to remember. Let's review the Onreadystate and onload events again.

 (function () {var retrieve = document.getElementById (' retrieve '), results = document
          . getElementById (' results '), toreadystatedescription = function (state) {switch (state) {case 0:
        return ' unsent ';
        Case 1:return ' opened ';
        Case 2:return ' headers_received ';
        Case 3:return ' LOADING ';
        Case 4:return ' done ';
      Default:return ';
  }
    };
    Retrieve.addeventlistener (' click ', Function (e) {var oreq = new XMLHttpRequest ();
    Oreq.onload = function () {Console.log (' Inside the OnLoad event ');
    }; Oreq.onreadystatechange = function () {Console.log (' Inside the onreadystatechange ev![
    Here you enter a description of the picture][1]ent with readyState: ' + toreadystatedescription (oreq.readystate));
    };
    Oreq.open (' Get ', E.target.dataset.url, true);
  Oreq.send ();
});
}()); 

The preceding code prints the following statement in the console (console):

The onReadyStateChange event can be triggered in any process that is requested. If you can before each request, at the end of the request. However, according to the document, the OnLoad event will only be triggered after the request succeeds. And because the OnLoad event is a common API, you can master it in a very short time. onReadyStateChange events can be reserved (original backwards compatible backwards compatible?) Programme And the OnLoad event should be your first choice. And the OnLoad event is similar to JQuery's success callback function, isn't it?

# # #设置请求头部
JQuery secretly helps you set the request head, so the backend can detect this is an AJAX request. In general, the backend does not care where a GET request comes from, as long as it returns the correct response. This comes in handy when you return Ajax or HTML with the same web API. Let's look at how to request headers through native JavaScript settings:

var oreq = new XMLHttpRequest ();
Oreq.open (' Get ', E.target.dataset.url, true);
Oreq.setrequestheader (' X-requested-with ', ' XMLHttpRequest ');
Oreq.send ();

At the same time, we do a test in Node.js:


if (req.headers[' x-requested-with '] = = ' XMLHttpRequest ') {
  res.writehead ' content-type ': ' application/ JSON '});
  Res.end (json.stringify ({message: ' Hello world! '})
}

As you can see, native Ajax is a flexible and modern front-end API. You can use the request head to do a lot of things, one of which is version control. For example, I want to have a web API that supports multiple versions. But I do not want to use the URL, instead: By setting the request headers, so that the client can choose the version they want. So, we can set the request head like this:

Oreq.setrequestheader (' x-vanillaajaxwithoutjquery-version ', ' 1.0 ');

Then, write the corresponding code on the back end:


if (req.headers[' x-requested-with '] = = ' XMLHttpRequest ' &&
  req.headers[' X-vanillaajaxwithoutjquery-version '] = = = ' 1.0 ') {
  //Send Ajax response
}

We can use Node.js to provide the headers object for us to detect accordingly. The only place to note is to read them in lowercase letters.

Response type
you may wonder why ResponseText returns a string rather than a normal JSON (Plain old JSON) that we can manipulate. It turns out that I didn't set the appropriate Responsetype attribute. The Ajax attribute is a good way to tell the data type that the front-end API expects the server to return. So we have to make good use of it:

var oreq = new XMLHttpRequest ();
Oreq.onload = function (e) {
  results.innerhtml = e.target.response.message;
};
Oreq.open (' Get ', E.target.dataset.url, true);
Oreq.responsetype = ' json ';
Oreq.send ();

Wow, so that we don't have to parse the returned plain text into JSON, we can tell the API what type of data we expect to receive. This feature is supported by almost all the latest mainstream browsers. Of course, JQuery will automatically help us get to the right type. But now native JavaScript also has a convenient way to accomplish the same thing. Native Ajax already supports many other response types, such as XML.

Unfortunately, the development team has not yet supported xhr.responsetype= ' JSON ' until IE11. Although this feature is currently supported at the Microsoft Edge. But this Bug has been raised for almost two years. I firmly believe that the Microsoft team has been working hard to improve the browser. Let's look forward to Microsoft Edge, aka Project Spartan's original commitment.
Of course, you can solve this IE problem with this:

Oreq.onload = function (e) {
  var xhr = e.target;
  if (Xhr.responsetype = = ' json ') {
    results.innerhtml = xhr.response.message;
  } else {
    results.innerhtml = Json.parse (xhr.responsetext). message;
  }
;

Avoid caching
The browser features that cache Ajax requests are quickly forgotten by us. For example, IE is the default. I have also been plagued by a few hours of frustration with my Ajax execution. Luckily, JQuery clears the browser cache by default. Of course, you can achieve that goal in pure Ajax, and quite simply:

var bustcache = '? ' + new Date (). GetTime ();
Oreq.open (' Get ', E.target.dataset.url + Bustcache, true);

Looking at the jquery document, you know that jquery appends a timestamp to the query string after each request (get). This makes the request unique to a certain extent and avoids browser caching. Whenever you trigger an HTTP Ajax request, you can see a request similar to the following:

Ok! There is no dramatic thing happening.

Summarize
I hope you enjoy this article about native Ajax. Ajax has been seen as a terrible monster for some time in the past. And in fact, we've covered all the basics of native Ajax.

Finally, I'll leave you with a concise way to make Ajax calls:

 var oreq = new XMLHttpRequest (); oreq.onload = function (e) {results.innerhtml = E.targ
Et.response.message;
};
Oreq.open (' Get ', E.target.dataset.url + '? ' + new Date (). GetTime (), true);
Oreq.responsetype = ' json '; 
Oreq.send (); 
Related Article

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.