웹브라우저는 보안을 위해 현재 도메인에서 다른 도메인으로의 요청을 원칙적으로 차단하고 있습니다. 따라서 다음과 같은 시도를 하게 되면
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script>
$(function () {
$.ajax({
url: 'https://www.naver.com/',
success: function (data) {
alert(data);
}
});
});
</script>
</head>
<body>
<div>
</div>
</body>
</html>
브라우저는 크로스 도메인 관련 오류를 내뿜게 됩니다.
위 문제를 해결하기 위한 방법으로는 대략 2가지 정도를 알아보고자 합니다.
1. JSONP
JSONP(JSON with Padding)는 다른 도메인에 요청을 보낼 때 callback매개변수를 보내면 응답을 보낼 때 JSON형태의 결과를 callback매개변수로 보낸 함수명으로 감싸 반환받는 형태를 의미합니다.
우선 예제작성을 위해 JSONP형태의 응답을 반환하는 서버를 만듭니다.
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public ActionResult JSONP(string callback)
{
var members = new List<Member>
{
new Member { Name = "홍길동", Age = 23, Address = "서울시" },
new Member { Name = "홍길순", Age = 40, Address = "부산시" },
new Member { Name = "홍길남", Age = 33, Address = "대구시" }
};
return Content(string.Format("{0}({1})", callback, JsonConvert.SerializeObject(members)));
}
}
public class Member
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
예제는 ASP.NET으로 작성하였으며 callback매개변수로 전달해 오는 이름으로 특정 내용을 json으로 감싸 반환하게 됩니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script type="text/javascript">
function cb(data)
{
alert(data);
}
</script>
</head>
<body>
<div>
</div>
</body>
<script type="text/javascript" src="http://server2016.cliel.com/home/jsonp?callback=cb"></script>
</html>
요청은 위와같이 할 수 있습니다. callback매개변수로 cb라는 이름을 전달했고 따라서 응답이 올 때는 cb라는 함 수명 안에 json객체를 담아올 것입니다. 그렇게 되면 자연스럽게 cb함수가 실행할 수 있게 됩니다.
jQuery를 통해 요청하는 경우라면 다음과 같이 할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script>
$(function () {
$.ajax({
url: 'http://server2016.cliel.com/home/jsonp',
dataType: 'jsonp',
success: function (data) {
alert(JSON.stringify(data));
}
});
});
</script>
</head>
<body>
<div>
</div>
</body>
</html>
jQuery에서는 dataType을 jsonp로 지정하는 경우 알아서 callback을 전달하므로 별도로 callback을 지정하지 않습니다.
보시는 바와같이 JSONP를 사용하면 크로스 도메인 간 통신이 가능하지만 제대로 이용하려면 응답을 하는 서버 쪽에서도 JSONP형식의 응답을 해줘야 하며 json데이터만 전달할 수 있습니다.
2. 서버에서 가져오기
다루고자 하는 데이터 형식이 json이 아니거나 기타 이유로 JSONP를 이용할 수 없는 상태라면 서버단 backend에서 필요한 데이터를 요청하고 응답을 받아 처리하는 형식을 취해야 합니다.
public ActionResult GetHTML()
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://www.daum.net/");
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(res.GetResponseStream());
return Content(reader.ReadToEnd());
}
위에서 작성환 ASP.NET코드에서 위 메서드를 추가합니다. 이 액션 메서드는 daum.net의 메인 페이지 HTML 소스를 긁어오는 동작을 수행합니다. 중요한 건 ASP.NET코드를 어떻게 작성하는가가 아니라 원하는 데이터를 가져오기 위해 서버에서 직접 요청을 하고 있다는 사실입니다.
서버를 통해 가져오는 경우라면 클라이언트에서는 타겟의 URL을 직접 호출하는 것이 아니라 서버의 URL을 통해 데이터를 가져올 수 있게 됩니다.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script>
$(function () {
$.ajax({
url: '/home/gethtml',
success: function (data) {
alert(data);
}
});
});
</script>
</head>
<body>
<div>
</div>
</body>
</html>
크로스 도메인은 어디까지나 웹브라우저 안에서만 제한되는 경우이므로 서버에서 직접 타 URL을 통해 원하는 데이터를 가져오는 우회적인 방법을 사용하는 것입니다.
'Web > Javascript' 카테고리의 다른 글
[Javascript] 웹브라우저 저장소 (0) | 2020.07.16 |
---|---|
[javascript] 쿠키(Cookies) (0) | 2020.07.04 |
[javascript] 예외 처리 (0) | 2020.05.30 |
[javascript] 이벤트 처리 (0) | 2020.05.29 |
[javascript] 문서 객체 다루기 (0) | 2020.05.27 |