Встраиваемые виджеты с использованием jQuery и ASP.NET MVC

Мне нужен совет по поводу наилучшего подхода к разработке встраиваемых виджетов, которые пользователи моего сайта могли бы использовать для отображения нашего контента на своем сайте.

Допустим, у нас есть некоторый контент, для отображения которого используется плагин jQuery, и мы хотим предоставить нашим клиентам простой способ встроить его в свои веб-сайты.

Одним из вариантов может быть использование IFrame, но, как мы знаем, это довольно инвазивно и имеет некоторые проблемы. Я хотел бы знать и ваше мнение по этому поводу.

Другой подход может заключаться в предоставлении кода, подобного этому, для отображения элемента № 23:

<DIV id="mysitewidget23"><script src="http://example.com/scripts/wdg.js?id=23" /></DIV>

И каким-то образом (здесь нужна помощь...) создание серверного скрипта wdg.js для вставки контента, jQuery, необходимых плагинов внутри DIV.

Это выглядит более многообещающе, так как пользователь может в определенной степени настроить стиль DIV, а IFRAME не требуется. Но какой способ сделать это в ASP.NET MVC лучше и эффективнее?

Конечно, есть много других подходов для достижения того, что нам нужно.


person marco    schedule 21.02.2010    source источник


Ответы (1)


JSONP — один из способов сделать это. Вы начинаете с написания пользовательского ActionResult, вернет JSONP вместо JSON, что позволит вам обойти междоменный Ajax ограничение:

public class JsonpResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;

        if (!string.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }

        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }

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

Затем вы можете написать действие контроллера, которое возвращает JSONP:

public ActionResult SomeAction()
{
    return new JsonpResult
    {
        Data = new { Widget = "some partial html for the widget" }
    };
}

И, наконец, люди могут вызывать это действие на своих сайтах с помощью jQuery:

$.getJSON('http://www.yoursite.com/controller/someaction?jsoncallback=?',
    function(json)
    {
        $('#someContainer').html(json.Widget);
    }
);

Если пользователи не хотят включать jQuery на свой сайт, вы можете написать код JavaScript на своем сайте, который будет включать jQuery и выполнять предыдущий вызов getJSON, чтобы людям нужно было включать только один файл JavaScript с сайта, как в вашем примере. .


ОБНОВИТЬ:

Как было сказано в разделе комментариев, вот пример, иллюстрирующий, как динамически загружать jQuery из вашего скрипта. Просто поместите следующее в свой файл JavaScript:

var jQueryScriptOutputted = false;
function initJQuery() {
    if (typeof(jQuery) == 'undefined') {
        if (!jQueryScriptOutputted) {
            jQueryScriptOutputted = true;
            document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js\"></scr" + "ipt>");
        }
        setTimeout("initJQuery()", 50);
    } else {
        $(function() {
            $.getJSON('http://www.yoursite.com/controller/someaction?jsoncallback=?',
                function(json) {
                    // Of course someContainer might not exist
                    // so you should create it before trying to set
                    // its content
                    $('#someContainer').html(json.Widget);
                }
            );
        });
    }
}
initJQuery();
person Darin Dimitrov    schedule 21.02.2010
comment
Это кажется очень умным решением, спасибо Дарин. Я реализовал его, и он работает хорошо, если я явно включу jquery и необходимые плагины на страницу клиента. Как вы догадались из вашего последнего абзаца, я хотел бы попытаться включить один тег ‹script› на свой сервер и включить в него jquery, но я не могу понять, как этого добиться. Я не могу добавить ‹script› явно в сгенерированный файл сценария, поэтому я попытался внедрить его с помощью document.write или eval, но безуспешно. Файл сценария jquery не интерпретируется, и следующий код завершается с ошибкой $ is undefined. любая идея?tnx - person marco; 21.02.2010
comment
Спасибо, выглядит многообещающе! Завтра попробую и дам знать! - person marco; 22.02.2010
comment
Привет, ребята, это выглядит как отличное решение, но я немного не уверен в чем-то: не могли бы вы объяснить, что означает эта строка? Data = new { Widget = "some partial html for the widget" } ? Является ли Widget каким-то пользовательским классом? Это частичное представление? Как в ActionMethod JsonpResult узнает, что такое тип Data? Где это определено? Спасибо - person DaveDev; 26.03.2010
comment
@DaveDev Widget — это простая переменная JSON. ASP.NET превратит его в { Widget: Your HTML } перед отправкой. На принимающей стороне, поскольку он преобразуется в объект JavaScript, в данном примере к нему может получить доступ json.Widget. - person NinjaBeetle; 27.07.2016