본문으로 건너뛰기

JS 학습노트 10_Ajax

무료2015-04-13#JS#Ajax

이 글에서는 Ajax 기술, XHR 객체의 사용 방법과 주의사항, 동일 출처 정책, 크로스도메인 방법, 크로스사이트 요청 위조 등에 대해 소개합니다

##1.Ajax 개요

Asynchronous JavaScript + XML, JavaScript 와 서버 간 통신을 지원합니다. 페이지를 unload 하지 않고 서버에서 새로운 데이터를 가져와 더 나은 사용자 경험을 실현합니다 (기존의 클릭 - 대기 인터랙션과는 다른 경험).

IE5 가 처음 지원을 제공했으며, MSXML 라이브러리에 XHR 객체 (XMLHttpRequest) 를 추가했습니다. new ActiveXObject(str) 로 XHR 객체를 생성할 수 있습니다. 편리하지는 않았지만, 적어도 네이티브 지원이었습니다

##2.XHR 객체

XMLHttpRequest, [IE6-] 는 XHR 객체의 구현이 다른 브라우저와 다르지만, 객체 감지를 통해 크로스브라우저 XHR 객체를 생성할 수 있습니다. 구체적인 코드는 다음과 같습니다:

/*获取 HttpRequest 对象,可以兼容各个浏览器 包括 IE5.5+*/
function getHttpObject(){
????if(typeof XMLHttpRequest == "undefined"){//如果该对象未定义,则自定义该对象
????????XMLHttpRequest = function(){
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP.6.0");
????????????}catch(e){}
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP.3.0");
????????????}catch(e){}
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP");
????????????}catch(e){}
????????????try{//老版本的 Internet Explorer(IE5 和 IE6)
????????????????return new ActiveXObject("Microsoft.XMLHTTP");
????????????}catch(e){}
?????????????
????????????return false;
????????}
????}
?????
????return new XMLHttpRequest();
}

XHR 객체의 속성은 다음과 같습니다:

  • responseText: 응답 바디

  • responseXML: 응답 콘텐츠가 "text/xml" 또는 "application/xml" 인 경우, 이 속성은 응답 데이터의 XML DOM 문서를 보관합니다

  • status: HTTP 응답 상태 (404, 200 등)

  • statusText: HTTP 상태 설명, 신뢰할 수 없습니다. 브라우저마다 다르므로 status 상태 코드를 사용하는 것이 가장 신뢰할 수 있습니다

  • readyState: 주로 비동기 요청에 사용됩니다. 동기 요청에서도 사용할 수 있지만 의미는 없습니다. readyState 의 5 개 값은 다음과 같습니다:

    • 0: 미초기화. open 메서드가 아직 호출되지 않았습니다

    • 1: 시작. open 은 호출되었지만 send 는 호출되지 않았습니다

    • 2: 전송. send 는 호출되었지만 응답을 받지 못했습니다

    • 3: 수신. 응답 데이터의 일부를 받았습니다

    • 4: 완료. 모든 데이터를 받았고 데이터를 사용할 수 있게 되었습니다

##3.XHR 객체를 사용하여 콜백 함수 실행

var xhr = getHttpObject();
xhr.onreadystatechange = function(){
??if(xhr.readyState === 4){
????if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){//本来只用检测 200 成功和 304 不变但有些浏览器会把 200 错报成 204
??????//执行 callback
????}
????else{
??????//请求失败
????}
??}
}

주의: readyystatechange 이벤트 핸들러를 open 함수에 설정해야 합니다. 모든 브라우저 호환성을 보장하기 위해서입니다

##4.XHR 객체를 사용하여 get/post 요청 실행

//get 请求
xhr.open('get', url, false/true);//初始化,false/true ~ 同步/异步
xhr.send(null);//发送请求,null 是为了兼容性
//post 请求
xhr.open('post', url, false/true);//同上
xhr.send(str);
/* 可以在 open 后 send 前设置请求头,比如添加 cookie 信息
xhr.setRequestHeader(strHeader, strValue);
*/

주의: 서버는 post 요청과 웹 폼 전송 요청의 처리 방식이 다르지만, HTTP 헤더를 수정하여 폼 전송을 시뮬레이션할 수 있습니다

하지만 폼 데이터를 전송하려면 send 의 매개변수 str 이 직렬화된 폼 데이터여야 합니다. 이 경우 직렬화 함수를 수동으로 구현해야 해서 번거롭습니다. JQuery 는 직렬화 지원을 제공하며, $('#mForm').serialize() 로 폼을 직접 직렬화할 수 있습니다

##5.요청中止

xhr.abort(); 응답이 반환되기 전에 요청을中止할 수 있습니다. abort 후 이벤트는 트리거되지 않으며, xhr 의 응답 관련 속성에도 액세스할 수 없습니다

주의: 요청을中止한 후 XHR 객체의 참조를 해제해야 합니다. XHR 객체 재사용은 권장되지 않습니다 (메모리 문제 때문)

##6.post 를 사용할까 get 을 사용할까?

post 요청은 더 많은 리소스를 소비하며, 데이터 전송 속도도 get 요청보다 훨씬 느립니다

하지만 get 요청은 안전하지 않으며, IE 에는 URI 길이 제한이 있습니다 (2048 바이트를 초과하지 않음). 따라서가능한 한 get 을 사용하고, 안 되면 post 를 사용합니다

##7.CORS 개요

Cross-Origin Resource Sharing, 크로스 오리진 리소스 공유, Ajax 는 동일 출처 정책의 제한을 받습니다. 일부 CORS 기술을 통해 동일 출처 정책의 제한을 깨뜨릴 수 있습니다. 예를 들어 IE8 의 XDR 객체

다른 브라우저는 XHR 객체를 확장하여 CORS 의 네이티브 지원을 구현했습니다: open 함수의 url 매개변수를 절대 URL 로 설정하면 됩니다

따라서모호함을 제거하기 위해, 로컬 리소스에 액세스할 때는 상대 URL 을 사용하고, 원격 리소스에 액세스할 때는 절대 URL 을 사용해야 합니다

##8.기타 크로스도메인 기술

  1. 이미지 Ping

    var img = new Image();
    img.onload = img.onerror = function(){
      //响应返回,执行回调函数
    }
    img.src = url;//一旦设置了 src 属性,就会立即请求(加载)图片,而不是把 img 元素插入 DOM 树后才开始
    

get 요청만 전송할 수 있으며, 서버의 응답 텍스트에 액세스할 수 없습니다. 주로 사용자의 페이지 클릭 추적 또는 동적 광고 노출 횟수에 사용됩니다

  1. JSONP

JSON with Padding, 브라우저와 서버 간 양방향 통신을 지원하며 응답 텍스트에 직접 액세스할 수 있습니다. 하지만 요청 실패 여부를 판단하기 어렵고, 다른 도메인에서 코드를 로드하여 실행하므로 보안 문제가 있습니다

크로스도메인 기술을 소개하는훌륭한블로그 글이 있습니다

##9.CSRF 공격

Cross-Site Request Forgery, 크로스사이트 요청 위조, 페이지에 직접 Ajax 코드를 삽입하며 동일 출처 정책의 제한이 없어 요청을 위조하여 민감한 데이터에 액세스합니다.

방지 방법은 다음과 같습니다:

  1. 리소스 액세스에 SSL 연결을 요구함

  2. 각 요청에 특수 알고리즘으로 계산된 인증 코드를 첨부해야 함을 요구함

댓글

아직 댓글이 없습니다

댓글 작성