原生JS实现Ajax和JSONP跨域请求

背景:

对接身份证录入和门锁卡号录入设备中,安装驱动完成后,提供的接口服务是http://localhost:8099/?cmd=readbcardid&charset=gbk,返回的数据格式如下:
在这里插入图片描述
要求在vue项目上实现JSONP跨域请求,不想因此加载第三方资源,于是利用原生JS构建简单的AJAX,还有跨域请求JSONP的实现

AJAX的根本是XMLHttprequest,而一个完整的AJAX请求一般包括以下步骤:

实例化XMLHttpRequest对象
连接服务器
发送请求
接收响应数据

下面直接上代码

ajax.js

const Ajax = (object) => {
	object = object || {};
	object.data = object.data || {};
	//判断请求类型为AJAX或者JSONP
	let json = object.jsonp ? Jsonp(object) : ajax(object);

	//设置ajax方法
	function ajax(object) {
	   // 1.设置请求方式:如果没有制定则默认为GET
	   object.type = (object.type || 'GET').toUpperCase();
	   // 2.设置data数据的格式化
	   object.data = formateObject(object.data);
	   // 3.实例化XMLHttpRequest对象
	   var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
	   // 4.监听事件,只要readyState改变,就会调用readystatechange事件
	   xhr.onreadystatechange = function(){
		   // readyState属性表示请求/响应过程的当前活动阶段,4为完成,已经接收到全部响应数据
		   if(xhr.readyState == 4) {
			   let status = xhr.status;
			   // status : HTTP响应的状态码,2开头表示成功
			   if(status >=200 && status < 300){
				   let response = '';
				   // 判断接受数据的内容类型
				   let type = xhr.getResponseHeader('Content-type');
				   if(type.indexOf('xml') !== -1 && xhr.responseXML) {
					  response = xhr.responseXML; //Document对象响应
					 } else if(type === 'application/json') {
					  response = JSON.parse(xhr.responseText); //JSON响应
					 } else {
					  response = xhr.responseText; //字符串响应
					};
					// 成功回调函数
					object.success && object.success(response);
			   }else {
					object.error && object.error(response);
			   }
		   }
	   }


	   // 5.连接和传输数据
	   if(object.type == 'GET') {
		   // 三个参数:请求方式、请求地址(get方式时,传输数据是加在地址后的)、是否异步请求(同步请求的情况极少);
		   xhr.open(object.type, object.url + '?' + object.data, true);
		   xhr.send(null);
		} else {
		   xhr.open(object.type, object.url, true);
		   //必须,设置提交时的内容类型
		   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		   // 传输数据
		   xhr.send(object.data);
		}
	}

	//设置Jsonp方法
	function Jsonp(object) {
	  // 创建script标签并加入到页面中
	  let callbackName = object.jsonp,
		  head = document.getElementsByTagName('head')[0];
	  // 设置传递给后台的回调参数名
	  object.data['callback'] = callbackName;
	  let data = formateObject(object.data),
		  script = document.createElement('script');
	  head.appendChild(script);
	  // 创建JSONP的回调函数
	  //创建jsonp回调函数
	  window[callbackName] = function(json) {
		  head.removeChild(script);
		  clearTimeout(script.timer);
		  window[callbackName] = null;
		  object.success && object.success(json);
	  };
	  // 发送请求
	  script.src = object.url + '?' + data;
	  //为了得知此次请求是否成功,设置超时处理
	  if(object.time) {
	   script.timer = setTimeout(function() {
		window[callbackName] = null;
		head.removeChild(script);
		object.error && object.error({
		 message: '请求超时'
		});
	   }, object.time);
	  }

	}


	//data的格式化方法
	function formateObject(data){
	   if(data){
		   let arr = [];
		   for(let name in data){
			   //encodeURIComponent() :用于对 URI 中的某一部分进行编码
			   arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
		   }

		   //为了防止缓存,在后面添加一个随机数
		   arr.push('randomV=' + randomNumber());
		   return arr.join('&');
	   }else {
		   console.error('无法格式化请求数据')
	   }
	}

	//生成随机数的方法
	function randomNumber(){
		return Math.floor(Math.random()*10000+404);
	}

}

export default Ajax;

使用

import Ajax from "@/utils/ajax"
// 身份证录入
export async function readIDCard(callback = () => {}) {
    try {
        Ajax({
            url : 'http://localhost:8099/',
            type : 'GET',
            jsonp : 'fnCallback',
            data : {
                cmd: "readbcardid",
                charset: "gbk",
            },
            time: 5000,
            success: (data) => {
                if (!data) {
                    return callback({
                        code: 500,
                        msg: "读卡失败,请重试"
                    });
                }
                switch (data.resultFlag) {
                    case 0: // 正常读卡
                        return callback({
                            code: 200,
                            msg: "读卡成功",
                            data: data.resultContent.cardid || ""
                        });
                    case -1: // 无卡
                        return callback({
                            code: 500,
                            msg: "请将身份证置于读卡器上"
                        });
                    case -2: // 读卡失败
                        return callback({
                            code: 500,
                            msg: "读卡失败,请检查卡是否置于读卡器上"
                        });
                    default:
                        return callback({
                            code: 500,
                            msg: "读卡失败,请检查卡是否置于读卡器上"
                        });
                }
            },
            error: function(ex){
                const {message} = ex;
                return callback({
                    code: 500,
                    msg: message
                });
            }
        })
    } catch (ex) {
        return callback({
            code: 500,
            msg: "读卡失败,请重试"
        });
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原生JS实现Ajax的步骤如下: 1. 首先,创建一个XMLHttpRequest对象。 2. 设置状态监听函数,监听请求的状态。 3. 使用`open`方法设置请求的类型(GET或POST)和URL。 4. 如果是跨域请求,需要处理跨域问题,例如设置请求头或者使用代理等方法。 5. 使用`send`方法发送请求,可以传递数据作为参数。 6. 在状态监听函数中,判断`readyState`和`status`的值是否满足请求成功的条件(readyState=4 & status=200)。 7. 如果请求成功,可以使用`responseText`或`responseXML`接收响应数据,并使用原生JS操作DOM进行显示。 8. 可以使用`JSON.parse`方法将响应数据解析成JSON格式。 跨域请求实现方法有多种,常见的方法包括JSONP、CORS、代理等。具体的实现方法需要根据具体的情况进行选择和配置。 请注意,跨域请求需要服务器端的支持和配置,否则会出现安全性问题。在开发时,需要注意跨域请求的规范和安全性考虑。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [原生js实现ajax以及ajax跨域请求](https://blog.csdn.net/qq_41720311/article/details/83991593)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [原生JS实现AjaxAjax跨域请求](https://blog.csdn.net/Geezer_007/article/details/100402235)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值