Home>

Usually use ajax to request data,Load a library (framework), maybe just use its ajax part.

Write an ajax, one can go through the process of handling problems,Improve technical capabilities,Second, sometimes I do n’t really need such a large library (framework) in my work. I wrote it myself.Why not do it.

First look at how popular jQuery calls ajax

$.ajax ({
  url:"test.php", //Send request URL string
  type:"get", //Send method
  datatype:"json", //The data type expected from the server xml, html, text, json, jsonp, script
  data:"k=v & k=v", //data sent
  async:true, //Asynchronous request
  cache:false, //cache
  timeout:5000, //timeout time in milliseconds
  beforesend:function () (), //Before the request
  error:function () (), //when the request fails
  success:function () {}, //When the request is successful
  complete:function () () //After the request is completed (regardless of success or failure)
});

Is this call very comfortable and convenient, if you feel comfortable, you can refer to this design method by yourself.Don't be too complicated,Just meet the needs.

First understand the basics of ajax

Xmlhttprequest object

The xmlhttprequest object is the core of Ajax. It sends an asynchronous request to the server through the xmlhttprequest objectGet data from the server,All modern browsers (ie7 +, firefox, chrome, safari, opera) support the xmlhttprequest object (ie5 and ie6 use activexobject).

Create a compatible xmlhttprequest object

var xhr=window.xmlhttprequest?new xmlhttprequest ():new activexobject ("microsoft.xmlhttp");

Send a request to the server

xhr.open (method, url, async);

//method:the type of request;get or post

//url:the requested url

//async:true (asynchronous) or false (synchronous)

xhr.send (string);

//Send the request to the server

//string:only used for post requests

//get is simpler and faster than the post request,And it works in most cases

//In the following cases,Please use the post request:

//Unable to use cache file (update file or database on server)

//Send a large amount of data to the server (post has no data volume limit)

//When sending user input containing unknown characters,post is more stable and reliable than get

Server response

Use the responsetext or responsexml property of the xmlhttprequest object to get the response from the server.

If the response from the server is xml and needs to be parsed as an xml object,Use the responsexml attribute.

If the response from the server is not xml, use the responsetext property. The responsetext property returns the response as a string.

Onreadystatechange event

When the request is sent to the server,We need to perform some response-based tasks.Whenever readystate changes, the onreadystatechange event is fired. The readystate property holds the state information of xmlhttprequest.

Three important attributes of the xmlhttprequest object:

onreadystatechange//Stored function (or function name), whenever the readystate property changes,Will call the function

readystate//The status of xmlhttprequest is stored, which changes from 0 to 4

0:request is not initialized

1:server connection is established

2:request received

3:request processing

4:The request is completed,And the response is ready

status//200:"ok", 404:Page not found

In the onreadystatechange event, we specify the task to be performed when the server response is ready to be processed, When readystate equals 4 and status is 200, the response is ready.

xhr.onreadystatechange=function () {
  if (xhr.readystate == 4 && xhr.status == 200) {
    //Ready to process the returned xhr.responsetext or xhr.responsexml
  }
};
</pre>
</div>
<p> A simple ajax request is as follows:
</p>
<div>
<pre>
var xhr=window.xmlhttprequest?new xmlhttprequest ():new activexobject ("microsoft.xmlhttp");
xhr.onreadystatechange=function () {
  if (xhr.readystate == 4 && xhr.status == 200) {
    //Ready to process the returned xhr.responsetext or xhr.responsexml
  }
};
xhr.open (method, url, async);
xhr.send (string);
</pre>
</div>
<p>
Supplement:1. When sending a get request, you may get cached results.
To avoid this,You can add a unique id and timestamp to the url. 2. If you need to post data like an html form, use setrequestheader () to add http headers. The data is then sent in the send () method.
</p>
<div>
<pre>
url +=(url.indexof ("?")<0?"?":"&") + "_ =" + (+ new date ());
xhr.setrequestheader ("content-type", "application/x-www-form-urlencoded");
</pre>
</div>
<p>
<Strong>
Start writing your own ajax
</strong>
</p>
<p>
First write a basic,Define various parameter options,for reference
</p>
<div>
<pre>
var $= (function () {
  //Auxiliary function serialization parameters
  function param (data) {
    //..
  }
  function ajax (opts) {
    var _opts={
      url:"/", //Send request url address
      type:"get", //how to send the request get (default), post
      datatype:"", //The data type expected from the server xml, html, text, json, jsonp, script
      data:null, //data sent "key=value & key=value", {key:value, key:value}
      async:true, //asynchronous request ture (default asynchronous), false
      cache:true, //cache ture (default cache), false
      timeout:5, //timeout time default 5 seconds
      load:function () (), //request loading
      error:function () (), //when the request fails
      success:function () (), //When the request is successful
      complete:function () () //After the request is completed (regardless of success or failure)
    }, aborted=false, key,    xhr=window.xmlhttprequest?new xmlhttprequest ():new activexobject ("microsoft.xmlhttp");
    for (key in opts) _opts [key]=opts [key];
    /*
    if (_opts.datatype.tolowercase () === "script") {
      //..
    }
    if (_opts.datatype.tolowercase () === "jsonp") {
      //..
    }
    * /
    if (_opts.type.touppercase () === "get") {
      if (param (_opts.data)! == "") {
        _opts.url +=(_opts.url.indexof ("?")<0?"?":"&") + param (_opts.data);
      }
      ! _opts.cache&&(_opts.url +=(_opts.url.indexof ("?")<0?"?":"&") + "_ =" + ( + new date ()));
    }
    function checktimeout () {
      if (xhr.readystate! == 4) {
        aborted=true;
        xhr.abort ();
      }
    }
    settimeout (checktimeout, _opts.timeout * 1000);
    xhr.onreadystatechange=function () {
      if (xhr.readystate! == 4) _opts.load&&_opts.load (xhr);
      if (xhr.readystate === 4) {
        var s=xhr.status, xhrdata;
        if (! aborted&&((s>= 200&&s<300) || s === 304)) {
          switch (_opts.datatype.tolowercase ()) {
            case "xml":
              xhrdata=xhr.responsexml;
            break;
            case "json":
              xhrdata=window.json&window.json.parse?json.parse (xhr.responsetext):eval ("(" + xhr.responsetext + ")");
            break;
            default:
              xhrdata=xhr.responsetext;
          }
          _opts.success&&_opts.success (xhrdata, xhr);
        } else {
          _opts.error&&_opts.error (xhr);
        }
        _opts.complete&&_opts.complete (xhr);
      }
    };
    xhr.open (_opts.type, _opts.url, _opts.async);
    if (_opts.type.touppercase () === "post") {
      xhr.setrequestheader ("content-type", "application/x-www-form-urlencoded");
    }
    xhr.send (_opts.type.touppercase () === "get"?null:param (_opts.data));
  }
  return {
    ajax:ajax
  }
}) ();

The parameter options are defined,Let's analyze it.The datatype is the focus of the entire ajax, and the simplicity or complexity of the code lies in it.

Data Here datatype is the data type expected by the server:xml, html, text, json, jsonp, script

1. When it is xml, the response from the server is xml, use the responsexml attribute to get the returned data

2. For html, text, json, use the responsetext property to get the returned data

A. When it is html, return plain text html information, whether the script tag contained in it is to be executed when the dom is inserted (code complexity +3)

B. When it is json, return json data, be safe, convenient, and compatible (code complexity +2)

3. When it is jsonp, it is generally used across domains.Instead of the original Ajax request, use the create script method (code complexity + 2)

4. For script:When cross domain,Instead of the original ajax request, use the create script method (code complexity +1);do not cross domain, return plain text javascript code, use the responsetext property to get the returned data (code complexity +1)

The script tag, jsonp, and script in the html fragment all use the method of creating the script tag.

Handling datatype as json

xhrdata=window.json&window.json.parse?json.parse (xhr.responsetext):eval ("(" + xhr.responsetext + ")");

This is the easiest way to deal with it,For json compatibility, you can use json2.js.

Handling datatype as jsonp

Jsonp is to request cross-domain through script tags,First understand the process:

This is requested in a.html in the picture above (requesting the url is the link in the ajax program), and the passed parameter callback=add is read in b.php. According to the obtained parameter value (value is add), js syntax generates function names,And passed the json data as a parameter to this function,Return the document generated by js syntax to a.html, a.html parses and executes the returned js document, and calls the defined add function.

It is generally called in the program in a more general way,For example, the following widely used loadjs function:

function loadjs (url, callback) {
  var doc=document, script=doc.createelement ("script"), body=doc.getelementsbytagname ("body") [0];
  script.type="text/javascript";
  if (script.readystate) {
    script.onreadystatechange=function () {
      if (script.readystate == "loaded" || script.readystate == "complete") {
        script.onreadystatechange=null;
        callback &&callback ();
      }
    };
  } else {
    script.onload=function () {
      callback &&callback ();
    };
  }
  script.src=url;
  body.appendchild (script);
}

Pass the requested URL into the loadjs function and get the same result.

loadjs ("http://www.b.com/b.php?callback=add");

Because the script is dynamically created, the request returns successfully,The js code is executed immediately,If the request fails, there is no prompt.Therefore, custom parameter options:_opts.success can be called, _opts.error cannot be called.

Ajax processing jsonp also has two cases:

1. The parameter callback=add after the request url is set, especially the function name add is defined, the request returns successfully,The js code is executed immediately (here is add ({"a":8, "b":2}))

2. Processing json data in _opts.success means that the request returns successfully,js code is not executed,And remove the parameters from the function,Returned as a parameter of _opts.success (here is equivalent to processing the string "add ({" a ":8," b ":2})", remove "add (" and ")" and get {"a":8, "b":2})

Handling datatype as html

If you do not process the script tag in the html fragment, you can directly insert the responsetext return value into the dom tree.If i want to process scripts, you need to find out the script tags in the html fragment.Buy a script separately,And note that the JS code contained in the script tag is still requested through src.

Handling datatype as script

If i want to cross domain,The method of creating a script is similar to the processing of jsonp;it does not cross domains and uses the responsetext property to obtain the returned data.You can use eval to make the code execute,You can also create scripts to execute.

function addjs (text) {
  var doc=document, script=doc.createelement ("script"), head=doc.getelementsbytagname ("body") [0];
  script.type="text/javascript";
  script.text=text;
  body.appendchild (script);
}

At this point, ajax is almost finished,Based on demand,Add various features,To think about how each function is implemented,And can find a solution.

The above is what we share with you without using a library (framework) to write ajax yourself, I hope everyone likes it.