/*
*
* 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(/</g,'<')
.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 <code>XmlHttpRequest.onreadystatechange</code> 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;
});
相关推荐
原生Ajax技术是Web开发中的一个关键组成部分,它允许网页在不刷新整个页面的情况下与服务器进行数据交互,实现异步通信。在这个场景中,我们讨论的是如何使用原生JavaScript代码来实现一个简单的异步提交功能,例如...
在IT行业中,尤其是在Web开发领域,原生AJAX(Asynchronous JavaScript and XML)和jQuery库是经常被用来创建动态交互式用户体验的技术。本篇博客主要探讨如何利用这两者实现二级联动选择,即当用户在一级选择中作出...
原生Ajax虽然功能强大,但代码相对复杂,因此在实际开发中,开发者往往会选择jQuery、axios、fetch等库或API来简化工作。然而,理解原生Ajax的工作原理对解决特定问题和优化性能具有重要意义。在"JavaScript案例-...
2. **jQuery的Ajax方法**:简化原生Ajax调用的库,如`$.ajax()`, `$.get()`, `$.post()`等。 3. **JSON数据格式**:Ajax传输数据的常见格式,轻量级且易于处理。 4. **Partial Rendering**:只更新页面的部分区域,...
- **简化操作:** 通过jQuery封装的$.ajax方法,大大简化了原生Ajax的代码,提高了开发效率。 - **易用性:** 提供了更多的默认设置,让开发者不需要编写大量的配置代码。 - **跨浏览器兼容:** jQuery内部对Ajax的...
通过原生Ajax,我们可以实现页面的异步数据获取,而通过封装Ajax函数,可以简化代码并提高复用性。在没有真实后端接口的情况下,使用Express和Node.js可以方便地创建模拟接口,供前端进行开发和测试。在实际项目中,...
然而,现代Web开发中,通常会使用像jQuery、axios或fetch这样的库来简化Ajax操作,因为它们提供了更多的功能和更好的浏览器兼容性。但了解原生实现有助于理解这些库的工作原理,对于进行更底层的问题排查和优化很有...
JavaScript中的AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个...随着技术的发展,现在更多地使用fetch API或jQuery等库来简化这一过程,但在理解基础的AJAX工作原理时,原生实现仍然是非常有价值的。
虽然现在有许多流行的JavaScript框架和库(如jQuery)简化了AJAX的实现,但在一些轻量级或特定场景下,了解如何用原生JavaScript实现AJAX也是非常有价值的。接下来,我们将详细介绍几种使用原生JavaScript实现AJAX的...
为了直观地展示jQuery如何简化代码,我们可以比较一下使用原生JavaScript和DOM操作与使用jQuery实现相同功能的例子。假设我们需要为页面上某个区域内的所有链接添加点击事件,询问用户是否确认访问链接。使用传统的...
在实际开发中,原生Ajax可能比较繁琐,因此现在常常使用像jQuery的`$.ajax()`或fetch API这样的工具来简化操作。 在压缩包文件名称列表中的"ajaxDemo"可能是包含了一个简单的Ajax请求示例的文件,可能包含HTML、...
### 使用jQuery简化Ajax开发 #### 一、简介与背景 jQuery 是一款流行的 JavaScript 库,由 John Resig 在 2006 年创建。它极大地简化了 JavaScript 的使用方式,尤其是在处理 DOM(Document Object Model)操作...
在Web开发中,数据的导入导出功能是十分..."grid2excel"这一功能的实现,简化了开发流程,使得这个过程变得更加简单和高效。在实际开发中,根据具体项目需求,可能还需要考虑兼容性、错误处理以及用户体验优化等问题。
它简化了Ajax的复杂性,让开发者可以专注于业务逻辑,而不是底层网络通信的细节。 在"zk-bin-3.6.3"这个压缩包中,包含的是ZK框架的3.6.3版本。这个版本可能包含了ZK运行所需的JAR文件、文档、示例代码和其他相关...
【jQuery简化Ajax开发】 jQuery是一个JavaScript库,它的主要目标是简化JavaScript和AJAX的编程,使得开发者能够以更简洁的方式处理DOM操作和异步数据交互。由John Resig创建于2006年,jQuery迅速成为了JavaScript...
jQuery 是一个强大的 JavaScript 库,它极大地简化了 DOM 操作、事件处理、动画效果以及Ajax交互等任务。本篇文章将详细介绍如何使用jQuery来简化Ajax开发,帮助初学者快速入门。 1. **DOM操作的简化** 在jQuery中...
这里以jQuery为例,它简化了Ajax操作。 ```html <!DOCTYPE html> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> $(document).ready(function() { $("#btnAjax").click(function() {...
原生AJAX处理JSON格式数据的实例代码主要涉及到Web开发中客户端与服务器端数据交互的知识点。AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个页面的情况下,能够更新部分网页的技术。JSON...
它们对"ajax.send"进行了封装,简化了代码。"ajax.get"方法会将参数拼接为查询字符串,并添加到URL中。"ajax.post"方法会将数据拼接为application/x-www-form-urlencoded格式的字符串,并作为请求体发送。 在使用...
**Ajax(Asynchronous JavaScript and XML)**是一种在无需重新加载整个网页的情况...通过深入学习和实践,你可以掌握更高级的Ajax技术,如使用jQuery或Vue.js等库简化Ajax操作,以及更复杂的服务器端逻辑和数据处理。