将 fullcalendar.io 与 JSONP 结合使用

Using fullcalendar.io with JSONP

我正在尝试将 public 个假期添加到完整日历中。 http://fullcalendar.io/

var actionUrl =  @Html.Raw(Json.Encode(@Url.Action("Calendar", "Lecture")));

        $('#fullcalendar').fullCalendar({
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            eventTextColor : "Black",
            eventSources: [

            {
                url: actionUrl,
                data: function() {
                    return {
                        campusIds: getCampusIds(),
                        lectureRoomIds: getLectureRoomsIds(),
                        lecturerIds: getLecturerIds(),
                        eventTypeIds: getEventTypeIds(),
                    }
                },
                error: function() {
                    alert('there was an error while fetching events!');
                },
                traditional: true
            },

            {
                url: "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=zaf?callback=?",
                error: function() {
                    alert('there was an error while fetching events!');
                },
            }
        ],

第一个事件源有效,它从我的 mvc 控制器中获取 json。然而,第二个来源没有。我知道我需要使用 jsonp 并且我认为我需要将返回的数据映射到完整日历可以理解的内容,但我无法做到这一点。请协助!

谢谢

首先,您需要使用有效参数调用 url,即

http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=1&year=2013&country=eng

这将 return 数据采用以下格式:

[{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}]

然后是将该数据转换为预期格式的情况,即 EventData

这是通过 objects return 迭代日期 json 来完成的,如下所示,但设置了您需要的属性(在下面的演示中,我设置了标题并开始):

  var items = [];
  $.each( json, function( key, val ) {
      items.push({ title : val.localName, start : val.date } );
  });

这一切都需要在 getJson 调用中完成,即

$.getJSON( "http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForMonth&month=3&year=2013&country=eng", function( data ) {

  $.each( data, function( key, val ) {
      items.push({ title : val.localName, start : val.date } );
  });  

});

您可以按如下方式设置您的日历项(为演示而简化):

$('#calendar').fullCalendar({
    events: items
});

jsFiddle

var items = [];
var json = [{"date":{"day":1,"month":1,"year":2015,"dayOfWeek":4},"localName":"New Year's Day","englishName":"New Year's Day"}]

  $.each( json, function( key, val ) {
      items.push({ title : val.localName, start : val.date } );
  });

$('#calendar').fullCalendar({
    events: items
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.js"></script>

<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.6/fullcalendar.css" rel="stylesheet"/>

<div id='calendar'></div>

修改后的答案

我找到了解决办法。您为约会使用的服务有 API 文档 here。相关部分:

JSONP

In each operation you can use JSONP like this: Sample URL returning public holidays in Austria for January 2013: JSON_URL?action=getPublicHolidaysForMonth&month=1&year=2013&country=aut&jsonp=myfunction

所以将 callback 更改为 jsonp 应该可以。此外,如果您提供一个范围而不是一个月,它最适合 FC。您的 ajax 调用应如下所示:

events: function (start, end, timezone, callback) {
    console.log(start.format('YYYY-MMM'));
    $.ajax({
        type: "get",
        url: 'http://kayaposoft.com/enrico/json/v1.0/?action=getPublicHolidaysForDateRange&jsonp=?',
        data: {
            country: "zaf",
            fromDate: start.format('DD-MM-YYYY'),
            toDate: end.format('DD-MM-YYYY')
        },
        dataType: 'jsonp',
        contentType: 'application/json',
        success: function (data) {
            var events = [];
            $.each(data, function (i, holiday) {
                events.push({
                    start: moment({
                        year: holiday.date.year,
                        month: holiday.date.month - 1, //momentjs uses base 0 months
                        day: holiday.date.day
                    }),
                    title: holiday.englishName,
                    allDay: true
                });
            });
            callback(events);
        }
    }).fail(function (jqXHR) {
        alert("failed to get holidays");
    });

这是一个有效的 JSFiddle.

旧答案:(仍然适用于非jsonp 服务器)

如果您尝试跨域json请求(jsonp),服务器需要支持。

JSONP 请求是 wrapped in script tags,因此必须是有效的 JS。文字对象不是有效的 JS(如 {a:'b'})。

jQuery 通过向服务器发送回调函数名称参数来处理此问题。看起来像:

callback=jQuery21003313164389692247_1423682275577

服务器必须将响应数据包装在此函数中,例如:

jQuery21003313164389692247_1423682275577( {id:"2",name:"me"} );

现在是有效且可执行的 JS。

因此,除非该服务器的 API 允许 JSONP 请求,否则您无法对其进行跨域请求。 这是网络浏览器的安全限制。

作为替代方案,您可以通过服务器代理数据。让 fullcalendar 向您的服务器发出请求,服务器又从外部源加载数据并将其发送回客户端。