재우니의 블로그

 

JSONP (JSON with Padding)는 cross origin ajax requests 을 허용하기 위해 잘 받아 들여진 해킹입니다. 요청을 일반적인 XHR / ajax 방식으로 만드는 대신 JSONP는 적절한 URL로 설정된 src 속성을 사용하여 DOM에 스크립트 태그를 동적으로 작성하여 결과를 반환합니다. 

 

브라우저는 스크립트 태그를 통해 로드되는 스크립트의 출처를 제한하지 않기 때문에 JavaScript를 통해 데이터를 JSONP를 지원하는 수백 개의 API 및 엔드 포인트에서 로드 할 수 있습니다.

 

 

 

 

$(function () {
        $.ajax({
            dataType: 'jsonp',
            url: 'http://otherdomain.com/Home/GetEmployees', //Normally this would be a url to an application on a different domain for JSONP
            success: function (data) {               
                var viewModel = {
                    FirstName: ko.observable(data[0].FirstName),
                    LastName: ko.observable(data[0].LastName),
                    Address: ko.observable( data[0].Address),
                    City: ko.observable (data[0].City),
                    Region: ko.observable(data[0].Region)
                };
                ko.applyBindings(viewModel);
              
            }
        });
    });

 

 

jQuery는 이미 JSONP 요청 및 결과를 쉽게 처리하도록 설정되어 있으며 버전 1.2 부터 JSONP를 지원했습니다.

MVC 애플리케이션에서 JSONP-스타일 데이터의 반환을 처리하는 가장 쉬운 방법 중 하나는 ActionResult 상속받아 JsonpResult 클래스를 만드는 것입니다

 

 

using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace JSONPExample.ActionResults
{
    public class JsonpResult : ActionResult
    {
         public string CallbackFunction { get; set; }
         public Encoding ContentEncoding { get; set; }
         public string ContentType { get; set; }
         public object Data { get; set; }
        public JsonpResult(object data) : this(data, null) { }
        public JsonpResult(object data, string callbackFunction)
        {
            Data = data;
            CallbackFunction = callbackFunction;
        }

        public override void ExecuteResult(ControllerContext context)
         {
             if (context == null) throw new ArgumentNullException("context");
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/x-javascript" : ContentType;

             if (ContentEncoding != null) response.ContentEncoding = ContentEncoding;
             if (Data != null)
            {
                HttpRequestBase request = context.HttpContext.Request;
                var callback = CallbackFunction ?? request.Params["callback"] ?? "callback";
                var serializer = new JavaScriptSerializer();
                 response.Write(string.Format("{0}({1});", callback, serializer.Serialize(Data)));
             }
         }
    }
}

 

 

사용하는 방법은 아래와 같이 해당 컨트롤러에서 모델을 JsonpResult 클래스를 통해 반환하면 됩니다.

public ActionResult GetEmployees()
        {
            var data =  GetDataSomehow();
             //constructor overload for overriding callback function:
            //return new JsonpResult(data, "callback function"); 
           return new JsonpResult(data);
        }

        private List<Employee> GetDataSomehow()
         {
             // Surrogate for getting some data from your database or other store
            List<Employee> emps = new List<Employee>();
            Employee emp = new Employee()
                               {
                                   Address = "123 High st.",
                                   BirthDate = DateTime.Parse("2/2/1980"),
                                   FirstName = "Joe",
                                   LastName = "Blow",
                                   City = "Yuma",
                                   Region ="AZ",
                                   Country = "US",
                                   EmployeeID = 1,
                                   HomePhone = "999-999-9999"
                               };
            emps.Add(emp);
            return emps;
        }

 

ExecuteResult 메서드는 요청 된 콜백의 이름을 사용하여 직렬화 된 JSON 데이터를 javascript 함수로 간단히 래핑합니다. 

이 반환 된 스크립트 블록은 클라이언트 페이지의 DOM 에 직접 삽입되고, 포함 된 JSON은 합법적인 자바 스크립트이므로 브라우저에서 실행됩니다. 

 

jQuery는 투명하게 처리하므로 개발자가 염려하는 한 다른 jQuery $ .ajax 호출과 똑같이 작동합니다.

 

 

1145921998_JSONPExample.zip
0.93MB / 0.93MB