Ajax通讯异常12002,简单化的原生ajax

本文详细解析了JavaScript库handpay.ajax的核心功能,包括request、get、post及form方法,支持异步请求、数据类型处理、错误处理等功能,适用于前后端交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

*

* path: seaAjax.js

* author: eric_wang

* date: 2014/10/22

*/

define(function(require,exports,module){

var handpay=handpay||{"version":"v.1.0.0"};

/**

* @namespace handpay.ajax 对XMLHttpRequest请求的封装

* @property success 请求失败的全局事件,function(String responseText,XMLHttpRequest xhr)

* @property error 请求失败的全局事件,function(XMLHttpRequest xhr)

* @property before 请求发送前触发的全局事件,function(XMLHttpRequest xhr)

*/

handpay.ajax = handpay.ajax || {};

/**

* 发送一个ajax请求

* @name handpay.ajax.request

* @function

* @grammar handpay.ajax.request(url[, options])

* @param {string}  url 发送请求的url

* @param {Object}  [options] 发送请求的选项参数

* @config {String}     [method]            请求发送的类型。默认为GET

* @config {String}     [dataType]            请求发送的类型。默认为GET

* @config {Boolean} [async]            是否异步请求。默认为true(异步)

* @config {Boolean} [cacheable]            是否缓存请求。默认为true(缓存)

* @config {String}     [data]              需要发送的数据。

* @config {Object}  [headers]           要设置的http request header

* @config {String}     [username]          用户

* @config {String}     [password]          密码

* @config {Function} [success]       请求成功时触发,function(string responseText,XMLHttpRequest xhr)

* @config {Function} [error]        请求失败时触发,function(XMLHttpRequest xhr)

* @config {Function} [before]   发送请求之前触发,function(XMLHttpRequest xhr)

* @config {Boolean} [noCache]          是否需要缓存,默认为true(缓存)

* @meta standard

* @see handpay.ajax.get,handpay.ajax.post,handpay.ajax.form

*

* @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象

*/

handpay.ajax.request=function(url,options){

options = options || {};

var data = options.data || "";

var async = !(options.async === false);// 是否异步请求。默认为true(异步)

var cacheable = !(options.async === false);

var username = options.username || "";

var password = options.password || "";

var method = (options.type || "GET").toUpperCase();

var dataType = (options.dataType || "HTML").toUpperCase();

var headers = options.headers || {};

var success = options.success || "";

var error = options.error || "";

var before = options.before || "";

var jsonp=options.jsonp || "jsonpcallback";  //jsonp的函数名称

var jsonpCallback=options.jsonp||"";

var charset=options.charset||"UTF-8";

var xhr;

/**HTML转义

* @param {string} [str]  需要转义的字符串

*/

function escape(str){

return str

.replace(/&/g,'&')

.replace(/

.replace(/>/g,'>')

.replace(/"/g,'"')

.replace(/'/g,''');

}

function firedEvent(callback){

switch(dataType){

case "TEXT":

if(callback){

callback(escape(xhr.responseText),xhr);

}

break;

case "JSON":

if(callback){

callback(parseJson(xhr.responseText),xhr);

}

break;

case "HTML":

default:

if(callback){

callback(xhr.responseText,xhr);

}

}

}

function parseJson(str){

if(typeof(str)==="object"){

return str;

}

if(JSON){

try{

return JSON.parse(str);

}catch(e){

return (new Function("return "+str))();

}

}else{

return (new Function("return "+str))();

}

}

//状态报告

function reportStatus(){

if (xhr.readyState == 4) {

var stat = xhr.status;

if (stat == 200) {

firedEvent(success);

} else {

// http://www.never-online.net/blog/article.asp?id=261

// case 12002: // Server timeout

// case 12029: // dropped connections

// case 12030: // dropped connections

// case 12031: // dropped connections

// case 12152: // closed by server

// case 13030: // status and statusText are unavailable

// IE error sometimes returns 1223 when it

// should be 204, so treat it as success

if ((stat >= 200 && stat < 300)

|| stat == 304

|| stat == 1223) {

firedEvent(success);

} else {

if(error){

error(xhr.responseText,xhr);

}

}

/*

* NOTE: Testing discovered that for some bizarre reason, on Mozilla, the

* JavaScript XmlHttpRequest.onreadystatechange handler

* function maybe still be called after it is deleted. The theory is that the

* callback is cached somewhere. Setting it to null or an empty function does

* seem to work properly, though.

*

* On IE, there are two problems: Setting onreadystatechange to null (as

* opposed to an empty function) sometimes throws an exception. With

* particular (rare) versions of jscript.dll, setting onreadystatechange from

* within onreadystatechange causes a crash. Setting it from within a timeout

* fixes this bug (see issue 1610).

*

* End result: *always* set onreadystatechange to an empty function (never to

* null). Never set onreadystatechange from within onreadystatechange (always

* in a setTimeout()).

*/

window.setTimeout(

function() {

// 避免内存泄露

xhr.onreadystatechange = new Function();

if (async) {

xhr = null;

}

}, 0);

}

}

}

/**

* 获取XMLHttpRequest对象

*

* @ignore

* @return {XMLHttpRequest} XMLHttpRequest对象

*/

function getXHR() {

if (window.ActiveXObject) {

try {

return new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try {

return new ActiveXObject("Microsoft.XMLHTTP");

} catch (e) {}

}

}

if (window.XMLHttpRequest) {

return new XMLHttpRequest();

}

}

//execute ajax request

function executeXhr(callback) {

xhr=getXHR();

if(cacheable){

try{

req.setRequestHeader("Cache-Control: no-store, no-cache, must-revalidate");

req.setRequestHeader("Connection","close");

} catch(e){}

}

//

var urlWithParam = url.split("?");//split the url in two parts

var urlPrefix = urlWithParam[0];//the url

var arg = urlWithParam[1];//the arguments

if(method == "POST") {//若为post请求提交则修改url值

url=urlPrefix;

}

if (username) {

xhr.open(method, url, async, username, password);

} else {

xhr.open(method, url, async);

}

if (async) {

xhr.onreadystatechange = callback;

}

xhr.setRequestHeader("Access-Control-Allow-Headers","X-Requested-With");

xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");

for (var key in headers) {

if (headers.hasOwnProperty(key)) {

xhr.setRequestHeader(key, headers[key]);

}

}

if(before){

before.call(this,xhr);

}

if(method == "POST") {

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

xhr.send(arg);

} else {

xhr.send();

}

if (!async) {

if(callback){

callback.call(this);

}

}

}

function loadScript(callback){

var head = document.head ||document.getElementsByTagName("head")[0]|| document.documentElement;

var script = document.createElement("script");

script.async = true;

//if ( s.scriptCharset ) {

script.charset = charset;

//}

script.src =url;

// Attach handlers for all browsers

script.onload = script.onreadystatechange = function( _, isAbort) {

if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {

// Handle memory leak in IE

script.onload = script.onreadystatechange = null;

// Remove the script

if ( script.parentNode ) {

script.parentNode.removeChild( script );

}

// Dereference the script

script = null;

// Callback if not abort

if ( !isAbort ) {

}else{

if(error){

error();

}

}

}

};

if(before){

jsonpFired(before);

}

if(success){

jsonpFired(success);

}

// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending

// Use native DOM manipulation to avoid our domManip AJAX trickery

head.insertBefore( script, head.firstChild );

//}

}

//jsonp 数据获取

function jsonpFired(callback){

//console.log(" window."+jsonpCallback+"=function(data){data=(new Function('return data'))();callback(data)}");

var fired=new Function("callbackfunction","parseJsonFun"," window."+jsonpCallback+"=function(data){data=parseJsonFun(data);callbackfunction(data);}");

fired(callback,parseJson);

}

(function(){

var callback = reportStatus;//default alert

if(data||dataType==="JSONP"){

if(url.indexOf("?")==-1){

url=url+"?";

}else{

url+="&";

}

if(dataType==="JSONP"){

if(!jsonpCallback){// jsonpCallback 参数为空或者没传的时候 重新生成函数名称

jsonpCallback="handpayAjax"+(new Date().getTime());

}

url+=jsonp+"="+jsonpCallback+"&";

}

if(data){

try{

if(typeof(data)==="object"){ //如果data参数是json对象 就转为参数的链式结构

for(var i in data){

if(data.hasOwnProperty(i)){

url+=i+"="+data[i]+"&";

}

}

if(!cacheable){

url+="t"+(new Date().getTime())+"=v1&";

}

url=url.substring(0,url.length-1);

}

}catch(e){

return null;

}

}

}

/*encode URL with Chinese*/

url = encodeURI(url);

//alert(url);

//execute the remote method

if(dataType==="JSONP"){

loadScript(callback);

}else{

executeXhr(callback);

}

})();

};

/**

* 发送一个post请求

* @name handpay.ajax.post

* @function

* @grammar handpay.ajax.post(url, data[, onsuccess])

* @param {string}  url         发送请求的url地址

* @param {string}  data        发送的数据

* @param {Function} [onsuccess] 请求成功之后的回调函数,function(XMLHttpRequest xhr, string responseText)

* @meta standard

* @see handpay.ajax.get,handpay.ajax.request

*

* @returns {XMLHttpRequest}    发送请求的XMLHttpRequest对象

*/

handpay.ajax.post = function (url, data, success) {

var options={};

options.method="POST";

options.data=data;

options.success=success;

return handpay.ajax.request(

url, options

);

};

/**

* 发送一个get请求

* @name handpay.ajax.get

* @function

* @grammar handpay.ajax.get(url[, onsuccess])

* @param {string}  url         发送请求的url地址

* @param {Function} [success] 请求成功之后的回调函数,function(string responseText,XMLHttpRequest xhr)

* @meta standard

* @see handpay.ajax.post,handpay.ajax.request

*

* @returns {XMLHttpRequest}    发送请求的XMLHttpRequest对象

*/

handpay.ajax.get = function (url,data,success) {

var options={};

options.method="GET";

options.data=data;

options.success=success;

return handpay.ajax.request(url,options);

};

/**

* 将一个表单用ajax方式提交

* @name handpay.ajax.form

* @function

* @grammar handpay.ajax.form(form[, options])

* @param {HTMLFormElement} form             需要提交的表单元素

* @param {Object}  [options]                   发送请求的选项参数

* @config {Boolean} [async]            是否异步请求。默认为true(异步)

* @config {String}     [username]          用户

* @config {String}     [password]          密码

* @config {Object}     [headers]           要设置的http request header

* @config {Function} [replacer]            对参数值特殊处理的函数,replacer(string value, string key)

* @config {Function} [before]     发送请求之前触发,function(XMLHttpRequest xhr)

* @config {Function} [success]        请求成功时触发,function(string responseText,XMLHttpRequest xhr)

* @config {Function} [error]        请求失败时触发,function(XMLHttpRequest xhr)

* @see handpay.ajax.request

*

* @returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象

*/

handpay.ajax.form = function (form, options) {

options = options || {};

var elements    = form.elements,

len         = elements.length,

method      = form.getAttribute('method'),

url         = form.getAttribute('action'),

replacer    = options.replacer || function (value, name) {

return value;

},

sendOptions = {},

data = [],

i, item, itemType, itemName, itemValue,

opts, oi, oLen, oItem;

/**

* 向缓冲区添加参数数据

* @private

*/

function addData(name, value) {

data.push(name + '=' + value);

}

// 复制发送参数选项对象

for (i in options) {

if (options.hasOwnProperty(i)) {

sendOptions[i] = options[i];

}

}

for (i = 0; i < len; i++) {

item = elements[i];

itemName = item.name;

// 处理:可用并包含表单name的表单项

if (!item.disabled && itemName) {

itemType = item.type;

itemValue = item.value;

switch (itemType) {

// radio和checkbox被选中时,拼装queryString数据

case 'radio':

case 'checkbox':

if (!item.checked) {

break;

}

// 默认类型,拼装queryString数据

case 'textarea':

case 'text':

case 'password':

case 'hidden':

case 'select-one':

addData(itemName, replacer(itemValue, itemName));

break;

// 多行选中select,拼装所有选中的数

case 'select-multiple':

opts = item.options;

oLen = opts.length;

for (oi = 0; oi < oLen; oi++) {

oItem = opts[oi];

if (oItem.selected) {

addData(itemName, replacer(oItem.value, itemName));

}

}

break;

}

}

}

// 完善发送请求的参数选项

sendOptions.data = data.join('&');

sendOptions.method = form.getAttribute('method') || 'POST';

// 发送请

return handpay.ajax.request(url, sendOptions);

};

module.exports=handpay.ajax;

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值