将 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
});
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 向您的服务器发出请求,服务器又从外部源加载数据并将其发送回客户端。
我正在尝试将 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
});
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 向您的服务器发出请求,服务器又从外部源加载数据并将其发送回客户端。