a, form 태그를 이용하지 않고 get, post 요청이 가능한지 궁금했다. 그래서 fetch api를 공부하던 중, internet Explorer에서는 fetch가 동작하지 않음을 발견했다. 이러한 발견은 fetch, axios 이전에는 서버에 새 페이지를 요청하지 않고 어떻게 데이터를 받아 페이지를 갱신할 수 있었을까? 하는 궁금증으로 이어졌다. explorer에서는 그것이 불가능 했던 것일까?
이러한 이유로 (XHR은 ajax, axios의 기반이 된다고 한다!), fetch를 정리하기 전에 XMLHttpRequest를 먼저 정리해보려고 한다. 이름만 보면 XML 데이터가 큰 역할을 하는 것 같지만, 예전 api들이 xml방식을 주로 썼어서 그런게 아닐지라는 추측이 남아있다고 한다. (최근에는 JSON이 많이 쓰인다.)
두가지 방법을 설명해보겠다. 먼저, 제일 많이 쓰이는 JSON을 이용하는 방법이다.
// jsonServer.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var bodyParser = require('body-parser');
// json 데이터를 파싱해주는 미들웨어.
// 이후 부터는 req.body를 통해 데이터 접근이 가능하다.
app.use(bodyParser.json());
// localhost:3000에 접속하면 jsonData.html 파일을 전송.
app.get('/', function (req, res) {
res.sendFile(__dirname + '/jsonData.html');
});
// /xml경로로 post 방식의 요청이 오면 그대로 재전송해준다.
// { data1: input } 객체가 올 것임.
app.post('/xml', function (req, res) {
res.send(req.body)
});
// 포트번호 3000번으로 서버 시작.
server.listen(3000, function () {
console.log('서버가 시작되었습니다.');
});
<!--jsonData.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body>
<script>
// xhr을 통해 새로고침 없이도 엘리멘트 갱신이 가능하다.
var xmlHttp = new XMLHttpRequest();
// readyState 속성이 변화할 때 마다 호출된다.
// https://developer.mozilla.org/ko/docs/Web/API/XMLHttpRequest/readyState
xmlHttp.onreadystatechange = function() {
if (this.status === 200 && this.readyState === this.DONE) {
// xhr의 response를 json 형태로 파싱한다.
// { data1: input } 객체가 올 것임.
let data = JSON.parse(xmlHttp.response);
document.querySelector("#responseData").innerHTML = data.data1;
}
}
// 클릭 시에 실행되는 함수
var xhr = function() {
var data1 = document.querySelector("#text1").value;
var jsonData = {
data1: data1
}
// 방식과 경로를 입력
xmlHttp.open("POST", "http://localhost:3000/xml");
// 컨텐츠 타입을 json으로 설정
xmlHttp.setRequestHeader('Content-type', 'application/json');
// 데이터를 json 형식으로 인코딩 후 전송
xmlHttp.send(JSON.stringify(jsonData));
document.querySelector("#requestData").innerHTML = data1;
}
</script>
<input type="text" id="text1" />
<button onclick="xhr()">xmlHttpRequest</button>
<div id="requestData">requestData</div>
<div id="responseData">responseData</div>
</body>
</html>
그 다음으로 x-www-form-urlencoded를 이용하는 방법이다. 실행 결과는 JSON 사용했을 때와 같다.
// server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var bodyParser = require('body-parser');
// x-www-form-urlencoded 타입의 post 요청을 파싱해준다.
app.use(bodyParser.urlencoded());
app.get('/', function (req, res) {
res.sendFile(__dirname + '/data.html');
});
app.post('/xml', function (req, res) {
res.send(req.body)
});
server.listen(3000, function () {
console.log('서버가 시작되었습니다.');
});
<!--Data.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body>
<script>
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (this.status === 200 && this.readyState === this.DONE) {
// JSON.parse()를 쓰지 않기 위한 노력 ㅠㅠ
let data = {};
let str = xmlHttp.response;
str = str.substring(1,str.length-1);
let props = str.split(',');
props.forEach(prop => {
let tmp = prop.split(':');
let key = tmp[0].substring(1, tmp[0].length-1)
let value = tmp[1].substring(1, tmp[1].length-1)
data[key] = value;
});
document.querySelector("#responseData").innerHTML = data['data1'];
}
}
var xhr = function() {
var data1 = document.querySelector("#text1").value;
var data = `data1=${data1}`;
xmlHttp.open("POST", "http://localhost:3000/xml");
// post 요청은 컨텐트 타입을 명시해줘야 한다.
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlHttp.send(data);
document.querySelector("#requestData").innerHTML = data1;
}
</script>
<input type="text" id="text1" />
<button onclick="xhr()">xmlHttpRequest</button>
<div id="requestData">requestData</div>
<div id="responseData">responseData</div>
</body>
</html>
developer.mozilla.org/ko/docs/Web/API/XMLHttpRequest#%EC%83%9D%EC%84%B1%EC%9E%90
www.tcpschool.com/xml/xml_dom_xmlHttpRequest
expressjs.com/ko/guide/routing.html
www.npmjs.com/package/express-xml-bodyparser
kamang-it.tistory.com/entry/RESTfulajaxajax%EB%9E%80-XMLHttpRequest%EC%82%AC%EC%9A%A9%EB%B2%95-1
unchae.tistory.com/entry/Multer-Nodejs%EB%A1%9C-Formdata-%EC%A0%84%EC%86%A1
www.codeproject.com/Questions/1102984/How-to-convert-string-to-object-in-javascript
coding-factory.tistory.com/143
untitledtblog.tistory.com/51?category=682814
'javascript' 카테고리의 다른 글
HTML 문서 렌더링 (0) | 2020.11.19 |
---|---|
fetch (0) | 2020.11.15 |
Promise (0) | 2020.11.03 |
정리할 web api 목록 (0) | 2020.09.16 |
;(세미콜론)생략 (0) | 2020.09.10 |