當(dāng)前位置:
首頁(yè) >
前端技术
> javascript
>内容正文
javascript
原生JS实现Ajax和JSONP跨域请求
生活随笔
收集整理的這篇文章主要介紹了
原生JS实现Ajax和JSONP跨域请求
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
背景:
對(duì)接身份證錄入和門鎖卡號(hào)錄入設(shè)備中,安裝驅(qū)動(dòng)完成后,提供的接口服務(wù)是http://localhost:8099/?cmd=readbcardid&charset=gbk,返回的數(shù)據(jù)格式如下:
要求在vue項(xiàng)目上實(shí)現(xiàn)JSONP跨域請(qǐng)求,不想因此加載第三方資源,于是利用原生JS構(gòu)建簡(jiǎn)單的AJAX,還有跨域請(qǐng)求JSONP的實(shí)現(xiàn)
AJAX的根本是XMLHttprequest,而一個(gè)完整的AJAX請(qǐng)求一般包括以下步驟:
實(shí)例化XMLHttpRequest對(duì)象
連接服務(wù)器
發(fā)送請(qǐng)求
接收響應(yīng)數(shù)據(jù)
下面直接上代碼
ajax.js
const Ajax = (object) => {object = object || {};object.data = object.data || {};//判斷請(qǐng)求類型為AJAX或者JSONPlet json = object.jsonp ? Jsonp(object) : ajax(object);//設(shè)置ajax方法function ajax(object) {// 1.設(shè)置請(qǐng)求方式:如果沒(méi)有制定則默認(rèn)為GETobject.type = (object.type || 'GET').toUpperCase();// 2.設(shè)置data數(shù)據(jù)的格式化object.data = formateObject(object.data);// 3.實(shí)例化XMLHttpRequest對(duì)象var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');// 4.監(jiān)聽(tīng)事件,只要readyState改變,就會(huì)調(diào)用readystatechange事件xhr.onreadystatechange = function(){// readyState屬性表示請(qǐng)求/響應(yīng)過(guò)程的當(dāng)前活動(dòng)階段,4為完成,已經(jīng)接收到全部響應(yīng)數(shù)據(jù)if(xhr.readyState == 4) {let status = xhr.status;// status : HTTP響應(yīng)的狀態(tài)碼,2開(kāi)頭表示成功if(status >=200 && status < 300){let response = '';// 判斷接受數(shù)據(jù)的內(nèi)容類型let type = xhr.getResponseHeader('Content-type');if(type.indexOf('xml') !== -1 && xhr.responseXML) {response = xhr.responseXML; //Document對(duì)象響應(yīng)} else if(type === 'application/json') {response = JSON.parse(xhr.responseText); //JSON響應(yīng)} else {response = xhr.responseText; //字符串響應(yīng)};// 成功回調(diào)函數(shù)object.success && object.success(response);}else {object.error && object.error(response);}}}// 5.連接和傳輸數(shù)據(jù)if(object.type == 'GET') {// 三個(gè)參數(shù):請(qǐng)求方式、請(qǐng)求地址(get方式時(shí),傳輸數(shù)據(jù)是加在地址后的)、是否異步請(qǐng)求(同步請(qǐng)求的情況極少);xhr.open(object.type, object.url + '?' + object.data, true);xhr.send(null);} else {xhr.open(object.type, object.url, true);//必須,設(shè)置提交時(shí)的內(nèi)容類型xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');// 傳輸數(shù)據(jù)xhr.send(object.data);}}//設(shè)置Jsonp方法function Jsonp(object) {// 創(chuàng)建script標(biāo)簽并加入到頁(yè)面中let callbackName = object.jsonp,head = document.getElementsByTagName('head')[0];// 設(shè)置傳遞給后臺(tái)的回調(diào)參數(shù)名object.data['callback'] = callbackName;let data = formateObject(object.data),script = document.createElement('script');head.appendChild(script);// 創(chuàng)建JSONP的回調(diào)函數(shù)//創(chuàng)建jsonp回調(diào)函數(shù)window[callbackName] = function(json) {head.removeChild(script);clearTimeout(script.timer);window[callbackName] = null;object.success && object.success(json);};// 發(fā)送請(qǐng)求script.src = object.url + '?' + data;//為了得知此次請(qǐng)求是否成功,設(shè)置超時(shí)處理if(object.time) {script.timer = setTimeout(function() {window[callbackName] = null;head.removeChild(script);object.error && object.error({message: '請(qǐng)求超時(shí)'});}, object.time);}}//data的格式化方法function formateObject(data){if(data){let arr = [];for(let name in data){//encodeURIComponent() :用于對(duì) URI 中的某一部分進(jìn)行編碼arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));}//為了防止緩存,在后面添加一個(gè)隨機(jī)數(shù)arr.push('randomV=' + randomNumber());return arr.join('&');}else {console.error('無(wú)法格式化請(qǐng)求數(shù)據(jù)')}}//生成隨機(jī)數(shù)的方法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: "讀卡失敗,請(qǐng)重試"});}switch (data.resultFlag) {case 0: // 正常讀卡return callback({code: 200,msg: "讀卡成功",data: data.resultContent.cardid || ""});case -1: // 無(wú)卡return callback({code: 500,msg: "請(qǐng)將身份證置于讀卡器上"});case -2: // 讀卡失敗return callback({code: 500,msg: "讀卡失敗,請(qǐng)檢查卡是否置于讀卡器上"});default:return callback({code: 500,msg: "讀卡失敗,請(qǐng)檢查卡是否置于讀卡器上"});}},error: function(ex){const {message} = ex;return callback({code: 500,msg: message});}})} catch (ex) {return callback({code: 500,msg: "讀卡失敗,請(qǐng)重試"});} }總結(jié)
以上是生活随笔為你收集整理的原生JS实现Ajax和JSONP跨域请求的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: vue.extend的问题
- 下一篇: JS 原生实现复选框全选反选功能