jQuery 是最流行的 JavaScript 库, 据调查, 互联网中近一半的网站都使用了 jQuery. 使用 jQuery, 开发者的编码工作将大大减少, 而大量的 jQuery 插件, 也使得开发者可以轻易实现很多绚丽的效果, 但是在 web 开发中, 并不是用到 JavaScript 的地方都适合使用 jQuery.
这几天我有一个的官网要制作, 由于网站比较小, 有一些与服务器通信的接口处理, 并没有涉及到复杂的交互功能. 为了可以减少加载 Jquery 库的时间, 也不用负担 Jquery 复杂的逻辑处理带来的性能消耗. 我决定不使用 jquery, 自己写了一个原生的 Ajax 函数.
一般来说, 前端与服务器的通信是使用 XHR 对象的. 我做的官网是有几个异域的接口, 然而 XHR 对象是没有跨域功能的. 所以我把 JSONP 整合进来.
下面是源码, 详细的解析说明, 请戳这里博客地址 http://littleblack.cc/2016/05/04/Javascript/自己动手写一个Ajax/ . 有任何的问题, 可以在我的博客下面留言. 任何留言我都会回复的哦
javascript 代码
- function ajax(options) {
- // 编码数据
- function setData() {
- var name, value;
- if (data) {
- if (typeof data === "string") {
- data = data.split("&");
- for (var i = 0, len = data.length; i <len; i++) {
- name = data[i].split("=")[0];
- value = data[i].split("=")[1];
- data[i] = encodeURIComponent(name) + "=" + encodeURIComponent(value);
- }
- data = data.replace("/ /g", "+");
- } else if (typeof data === "object") {
- var arr = [];
- for (var name in data) {
- var value = data[name].toString();
- name = encodeURIComponent(name);
- value = encodeURIComponent(value);
- arr.push(name + "=" + value);
- }
- data = arr.join("&").replace("/ /g", "+");
- }
- // 若是使用 get 方法或 JSONP, 则手动添加到 URL 中
- if (type === "get" || dataType === "jsonp") {
- url += url.indexOf("?")> -1 ? data : "?" + data;
- }
- }
- }
- // JSONP
- function createJsonp() {
- var script = document.createElement("script"),
- timeName = new Date().getTime() + Math.round(Math.random() * 1000),
- callback = "JSONP_" + timeName;
- window[callback] = function(data) {
- clearTimeout(timeout_flag);
- document.body.removeChild(script);
- success(data);
- }
- script.src = url + (url.indexOf("?")> -1 ? "":"?") +"callback=" + callback;
- script.type = "text/javascript";
- document.body.appendChild(script);
- setTime(callback, script);
- }
- // 设置请求超时
- function setTime(callback, script) {
- if (timeOut !== undefined) {
- timeout_flag = setTimeout(function() {
- if (dataType === "jsonp") {
- delete window[callback];
- document.body.removeChild(script);
- } else {
- timeout_bool = true;
- xhr && xhr.abort();
- }
- console.log("timeout");
- }, timeOut);
- }
- }
- // XHR
- function createXHR() {
- // 由于 IE6 的 XMLHttpRequest 对象是通过 MSXML 库中的一个 ActiveX 对象实现的.
- // 所以创建 XHR 对象, 需要在这里做兼容处理.
- function getXHR() {
- if (window.XMLHttpRequest) {
- return new XMLHttpRequest();
- } else {
- // 遍历 IE 中不同版本的 ActiveX 对象
- var versions = ["Microsoft", "msxm3", "msxml2", "msxml1"];
- for (var i = 0; i <versions.length; i++) {
- try {
- var version = versions[i] + ".XMLHTTP";
- return new ActiveXObject(version);
- } catch (e) {}
- }
- }
- }
- // 创建对象.
- xhr = getXHR();
- xhr.open(type, url, async);
- // 设置请求头
- if (type === "post" && !contentType) {
- // 若是 post 提交, 则设置 content-Type 为 application/x-www-four-urlencoded
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
- } else if (contentType) {
- xhr.setRequestHeader("Content-Type", contentType);
- }
- // 添加监听
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- if (timeOut !== undefined) {
- // 由于执行 abort() 方法后, 有可能触发 onreadystatechange 事件,
- // 所以设置一个 timeout_bool 标识, 来忽略中止触发的事件.
- if (timeout_bool) {
- return;
- }
- clearTimeout(timeout_flag);
- }
- if ((xhr.status>= 200 && xhr.status < 300) || xhr.status == 304) {
- success(xhr.responseText);
- } else {
- error(xhr.status, xhr.statusText);
- }
- }
- };
- // 发送请求
- xhr.send(type === "get" ? null : data);
- setTime(); // 请求超时
- }
- var url = options.url || "", // 请求的链接
- type = (options.type || "get").toLowerCase(), // 请求的方法, 默认为 get
- data = options.data || null, // 请求的数据
- contentType = options.contentType || "", // 请求头
- dataType = options.dataType || "", // 请求的类型
- async = options.async === undefined && true, // 是否异步, 默认为 true.
- timeOut = options.timeOut, // 超时时间.
- before = options.before || function() {}, // 发送之前执行的函数
- error = options.error || function() {}, // 错误执行的函数
- success = options.success || function() {}; // 请求成功的回调函数
- var timeout_bool = false, // 是否请求超时
- timeout_flag = null, // 超时标识
- xhr = null; //xhr 对角
- setData();
- before();
- if (dataType === "jsonp") {
- createJsonp();
- } else {
- createXHR();
- }
- }
来源: http://www.qdfuns.com/article/23931/ca7d9d1941d3df86c55368de239d8818.html