이 글에서는 비동기 데이터 요청을 보내기 위한 기본 JS 관련 정보를 주로 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.
프로젝트를 하다 보면 가끔 비동기 데이터 요청을 사용해야 하는 경우가 있습니다. 현재 프레임워크 종속성이 없으므로 비동기 데이터 요청을 수행하려면 기본 JS를 사용해야 합니다. 현재 요청 방법은 두 가지뿐입니다. 하나는 AJAX이고 다른 하나는 JSONP입니다. 네이티브 JS를 통해 비동기 요청을 간단하게 캡슐화합니다.
AJAX
AJAX는 전체 페이지를 새로 고치지 않고도 부분 페이지의 데이터를 업데이트할 수 있는 데이터 요청 방식입니다. AJAX의 기술 핵심은 XMLHttpRequest 객체입니다. 주요 요청 프로세스는 다음과 같습니다.
XMLHttpRequest 객체 생성(신규)
서버에 연결(열기)
요청 보내기(보내기)
응답 데이터 수신(onreadystatechange)
아무 말도 하지 않고 직접 코드 게시
/** * 通过JSON的方式请求 * @param {[type]} params [description] * @return {[type]} [description] */ ajaxJSON(params) { params.type = (params.type || 'GET').toUpperCase(); params.data = params.data || {}; var formatedParams = this.formateParams(params.data, params.cache); var xhr; //创建XMLHttpRequest对象 if (window.XMLHttpRequest) { //非IE6 xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //异步状态发生改变,接收响应数据 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { if (!!params.success) { if (typeof xhr.responseText == 'string') { params.success(JSON.parse(xhr.responseText)); } else { params.success(xhr.responseText); } } } else { params.error && params.error(status); } } if (params.type == 'GET') { //连接服务器 xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true); //发送请求 xhr.send(); } else { //连接服务器 xhr.open('POST', params.url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //发送请求 xhr.send(formatedParams); } }, /** * 格式化数据 * @param {Obj} data 需要格式化的数据 * @param {Boolean} isCache 是否加入随机参数 * @return {String} 返回的字符串 */ formateParams: function(data, isCache) { var arr = []; for (var name in data) { arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); } if (isCache) { arr.push('v=' + (new Date()).getTime()); } return arr.join('&'); }
IE7 이상에서는 기본 XHR 개체를 지원하므로 직접 사용할 수 있습니다. var oAjax = new XMLHttpRequest() ;. IE6 및 이전 버전에서는 XHR 개체가 MSXML 라이브러리의 ActiveXObject 개체를 통해 구현되었습니다.
xhr의 공개 기능을 통해 서버에 연결합니다. 이 기능은 주로 요청 방법, 요청 주소, 비동기 요청 여부(일반적으로 비동기 요청)의 세 가지 매개변수를 받습니다. 요청 방식에는 GET과 POST 두 가지가 있는데, GET은 URL을 통해 서버에 데이터를 제출하고, POST는 send 방식의 매개변수로 데이터를 서버에 보냅니다.
상태 변경 함수 onreadystatechange를 xhr에 바인딩합니다. 이는 주로 xhr의 ReadyState 변경을 감지하는 데 사용됩니다. 비동기 전송이 성공하면 ReadyState 값이 0에서 4로 변경되고 onreadystatechange 이벤트가 트리거됩니다. 동시. ReadyState의 속성 및 해당 상태는 다음과 같습니다.
0 (uninitialized) 객체가 설정되었지만 초기화되지 않았습니다 (open 메소드가 아직 호출되지 않음)
1 (Initialized) 객체가 설정되었습니다. 하지만 send 메소드가 아직 호출되지 않았습니다
2 (데이터 보내기) 전송 메소드가 호출되었지만 현재 상태와 http 헤더를 알 수 없습니다
3 (데이터 전송 중) 응답이 있기 때문에 데이터의 일부가 수신되었습니다. 이때 responseBody 및 responseText를 통해 일부 데이터를 가져오면 오류가 발생합니다.4 (완료) 데이터 수신이 완료되었으며, 이 때 responseBody 및 responseText를 통해 완전한 응답 데이터를 얻을 수 있습니다. Readystatechange 이벤트에서는 먼저 응답 수신 여부를 확인한 후 서버가 요청을 성공적으로 처리했는지 확인합니다. xhr.status는
상태 코드
이고 상태 코드는 2로 시작합니다. All are 성공적인, 304는 위의 코드는 각 요청에 임의의 숫자를 추가하므로 캐시에서 값을 가져오지 않으므로 이 상태를 판단할 필요가 없습니다.
여전히 위의 XMLHttpRequest 객체를 사용하여 도메인 간 요청을 보내는 경우 보내기 기능이 호출되더라도 xhr 상태는 항상 0이며 onreadystatechange 이벤트가 트리거되지 않습니다. 이번에는 JSONP 요청 방법입니다.
JSONP(JSON with Padding)는 도메인 간 요청 방법입니다. 주요 원칙은 스크립트 태그의 도메인 간 요청 기능을 활용하고 src 속성을 통해 서버에 요청을 보내고, 서버는 js 코드를 반환하고, 웹 페이지는 응답을 수락한 다음 직접 실행하는 것입니다. 이는 스크립트 태그를 통해 외부 파일을 참조하는 원리와 동일합니다.콜백 함수
와 데이터의 두 부분으로 구성됩니다. 콜백 함수는 일반적으로 웹 페이지에 의해 제어되며 서버는 함수와 데이터를 문자열로 결합하여 반환합니다.
예를 들어 웹 페이지는 스크립트 태그를 생성하고 해당 src 값을 http://www.test.com/json/?callback=process
에 할당합니다. 이때 웹 페이지는 요청을 시작합니다. 서버는 반환할 데이터를
/** * 通过JSONP的方式请求 * @param {[type]} params [description] * @return {[type]} [description] */ ajaxJSONP(params) { params.data = params.data || {}; params.jsonp = params.jsonp || 'callback'; // 设置传递给后台的回调参数名和参数值 var callbackName = 'jsonp_' + (new Date()).getTime(); params.data[params.jsonp] = callbackName; var formatedParams = this.formateParams(params.data, params.cache); //创建script标签并插入到页面中 var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); head.appendChild(script); //创建jsonp回调函数 window[callbackName] = function(json) { head.removeChild(script); clearTimeout(script.timer); window[callbackName] = null; params.success && params.success(json); }; //发送请求 script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url); //为了得知此次请求是否成功,设置超时处理 if (params.time) { script.timer = setTimeout(function() { window[callbackName] = null; head.removeChild(script); params.error && params.error({ message: '超时' }); }, params.time); } }
src 속성을 스크립트 태그로 설정하면 브라우저가 요청을 보내지만 요청은 한 번만 보낼 수 있으므로 스크립트 태그를 재사용할 수 없으므로 스크립트 태그를 제거해야 합니다. 각 작업 후. 브라우저가 요청을 보내기 전에 콜백 함수를 전역적으로 바인딩합니다. 이 콜백 함수는 데이터 요청이 성공하면 호출됩니다.
Summary
var xyfAjax = { ajax: function(params) { params = params || {}; params.cache = params.cache || false; if (!params.url) { throw new Error('参数不合法'); } params.dataType = (params.dataType || 'json').toLowerCase(); if (params.dataType == 'jsonp') { this.ajaxJSONP(params); } else if (params.dataType == 'json') { this.ajaxJSON(params); } }, /** * 通过JSONP的方式请求 * @param {[type]} params [description] * @return {[type]} [description] */ ajaxJSONP(params) { params.data = params.data || {}; params.jsonp = params.jsonp || 'callback'; // 设置传递给后台的回调参数名和参数值 var callbackName = 'jsonp_' + (new Date()).getTime(); params.data[params.jsonp] = callbackName; var formatedParams = this.formateParams(params.data, params.cache); //创建script标签并插入到页面中 var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); head.appendChild(script); //创建jsonp回调函数 window[callbackName] = function(json) { head.removeChild(script); clearTimeout(script.timer); window[callbackName] = null; params.success && params.success(json); }; //发送请求 script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url); //为了得知此次请求是否成功,设置超时处理 if (params.time) { script.timer = setTimeout(function() { window[callbackName] = null; head.removeChild(script); params.error && params.error({ message: '超时' }); }, params.time); } }, /** * 通过JSON的方式请求 * @param {[type]} params [description] * @return {[type]} [description] */ ajaxJSON(params) { params.type = (params.type || 'GET').toUpperCase(); params.data = params.data || {}; var formatedParams = this.formateParams(params.data, params.cache); var xhr; //创建XMLHttpRequest对象 if (window.XMLHttpRequest) { //非IE6 xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //异步状态发生改变,接收响应数据 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { if (!!params.success) { if (typeof xhr.responseText == 'string') { params.success(JSON.parse(xhr.responseText)); } else { params.success(xhr.responseText); } } } else { params.error && params.error(status); } } if (params.type == 'GET') { //连接服务器 xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true); //发送请求 xhr.send(null); } else { //连接服务器 xhr.open('POST', params.url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //发送请求 xhr.send(formatedParams); } }, /** * 格式化数据 * @param {Obj} data 需要格式化的数据 * @param {Boolean} isCache 是否加入随机参数 * @return {String} 返回的字符串 */ formateParams: function(data, isCache) { var arr = []; for (var name in data) { arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); } if (isCache) { arr.push('v=' + (new Date()).getTime()); } return arr.join('&'); } } xyfAjax.ajax({ url:'http://www.xieyufei.com', type:'get', //or post dataType:'json', //or jsonp data:{ name:'xyf' }, success: function(data){ console.log(data) } })
위 내용은 비동기 데이터 요청 예제를 보내는 네이티브 JS에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!