2

我正在开发一个涉及跨域调用的 Web 项目,我决定使用 Knockout.js 和 ASP.NET Web Api。我在 VS 2012 中使用了单页应用程序模板,并按原样实现了 Knockout 类。当我从同一个域进行 JSON 调用时,该页面效果很好,但是当我尝试从远程服务器使用 JSONP 时,敲除似乎没有绑定数据。在进行 JSONP 调用时,我可以看到从远程接收到的 JSON 数据,但是敲除无法绑定数据。

这是我的 JavaScript ViewModel 类:

window.storyApp.storyListViewModel = (function (ko, datacontext) {
    //Data
    var self = this;
    self.storyLists = ko.observableArray();
    self.selectedStory = ko.observable();   
    self.error = ko.observable();

    //Operations
    //Load initial state from the server, convert it to Story instances, then populate self

    datacontext.getStoryLists(storyLists, error); // load update stories      

    self.selectStory = function (s) {
        selectedStory(s); $("#showStoryItem").click(); window.scrollTo(0, 0);
        storyItem = s;        
    }
    //append id to the hash for navigating to anchor tag
    self.backToStory = function () {        
        window.location.hash = storyItem.id;       
    }

    self.loadStories = function () {
        datacontext.getStoryLists(storyLists, error); // load update stories
    }

    return {
        storyLists: self.storyLists,
        error: self.error,        
        selectStory: self.selectStory
    };
})(ko, storyApp.datacontext);

// Initiate the Knockout bindings
ko.applyBindings(window.storyApp.storyListViewModel);

我的 DataContext 类如下:

window.storyApp = window.storyApp || {};

window.storyApp.datacontext = (function (ko) {

    var datacontext = {
        getStoryLists: getStoryLists
    };

    return datacontext;

    function getStoryLists(storyListsObservable, errorObservable) {
        return ajaxRequest("get", storyListUrl())
            .done(getSucceeded)
            .fail(getFailed);

        function getSucceeded(data) {
            var mappedStoryLists = $.map(data, function (list) { return new createStoryList(list); });
            storyListsObservable(mappedStoryLists);
        }

        function getFailed() {
            errorObservable("Error retrieving stories lists.");
        }

        function createStoryList(data) {
            return new datacontext.StoryList(data); // TodoList is injected by model.js
        }
    }

    // Private
    function clearErrorMessage(entity) {
        entity.ErrorMessage(null);
    }

    function ajaxRequest(type, url, data) { // Ajax helper
        var options = {
            dataType: "JSONP",
            contentType: "application/json",
            cache: false,
            type: type,
            data: ko.toJSON(data)
        };
        return $.ajax(url, options);
    }

    // routes
    function storyListUrl(id) {
        return "http://secure.regis.edu/insite_webapi/api/story/" + (id || "");
    }
})(ko);

此页面:http : //insite.regis.edu/insite/index.html 对secure.regis.edu 进行跨域调用,但它不起作用。然而,在secure.regis.eduinsite/index.html 上进行JSON 调用的同一页面工作得很好。

我究竟做错了什么?任何帮助将不胜感激。

4

2 回答 2

2

感谢那些提供的帮助。

我设法通过将 WebApiContrib.Formatting.Jsonp 类添加到我的 WebApi 项目中来解决该问题,如https://github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp中所述,并对我的 jQuery Ajax 帮助程序类进行如下轻微修改:

function ajaxRequest(type, url, data, callbackWrapper) { // Ajax helper
    var options = {
        dataType: "jsonp",
        crossDomain : true,
        type: type,
        jsonp: "callback",
        jsonpCallback: callbackWrapper,
        data: ko.toJSON(data)
    };   

    return $.ajax(url, options);
}

一切都像魅力一样。

于 2013-02-04T18:05:09.153 回答
1

我建议如下:

创建一个简化的示例(没有 Knockout),它只使用简单的警报式成功和错误回调进行 AJAX 调用。确认它在跨域情况下抛出错误。

检查以下链接:jQuery.ajax request with jsonp content type 之后的 parsererror。如果这还不够,请在 Web(和 StackOverflow)上搜索有关 jQuery JSONP 解析错误和回调的信息。

如果您仍然卡住,并且您已经完成了 #1 并看到了我希望您会看到的内容,请使用您的简化示例重新编写这篇文章,并删除对 Knockout 的所有引用(在标题、标签中)。我知道 Knockout,但我不知道 JSONP,而知道 JSONP 的人似乎并没有接触到这个,所以我认为这个问题的受众是错误的。更改标题和标签以强调 JSONP/跨域方面可能会为您提供所需的帮助。

于 2013-01-31T06:06:37.603 回答