简体   繁体   English

Javascript 生成的 .ics 文件可以在 Chrome 和 Firefox 中打开,但不能在 IE 中打开

[英]Javascript-generated .ics file opens in Chrome and Firefox, but not in IE

I'm generating a .ics calendar entry from JS, next I open it using a data-URI:我正在从 JS 生成一个 .ics 日历条目,接​​下来我使用数据 URI 打开它:

window.open("data:text/calendar;charset=utf8," + escape(icsMSG));

Where "icsMSG" is the dynamically generated .ics file.其中“icsMSG”是动态生成的 .ics 文件。 Here's a sample output from console.log:这是来自 console.log 的示例输出:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//www.jungledragon.com//NONSGML v1.0//EN
BEGIN:VEVENT
UID:info@jungledragon.com
DTSTAMP:20140321T153010Z
ATTENDEE;CN=My Self ;RSVP=FALSE
CATEGORIES:APPOINTMENT
DTSTART:20140321T153010Z
DTEND:
LOCATION:5384 DA Heesch, The Netherlands
SUMMARY:JungleDragon Daylight Event
DESCRIPTION:Hey you!   \n \n  At this time in your calendar light conditions are great for the location you selected:\n \nhttp://www.ignore.org/apps/jd3/daylight#date=1392996610000&lat=51.73171&long=5.527827000000002\n\nHappy shooting, and be sure to share your wildlife photos back to http://www.jungledragon.com\nCheers,\nThe JungleDragon Team
END:VEVENT
END:VCALENDAR

The raw output will be have \\n chars at the end of each line, as per the specification.根据规范,原始输出将在每行末尾包含 \\n 个字符。

The above sample works fine when I run it from Chrome or Firefox, in both case it will open up my default Calendar application (Outlook 2013).当我从 Chrome 或 Firefox 运行它时,上面的示例工作正常,在这两种情况下,它都会打开我的默认日历应用程序(Outlook 2013)。 In IE(11) and Opera, instead something weird happens.在 IE(11) 和 Opera 中,发生了一些奇怪的事情。 A new tab opens that has the above string as the URL, with all special chars URL-escaped.将打开一个新选项卡,将上述字符串作为 URL,所有特殊字符都经过 URL 转义。 Like so:像这样:

data:text/calendar;charset=utf8,BEGIN%3AVCALENDAR%0AVERSION%3A2.0%0APRODID%3A-//www.jungledragon.com//NONSGML%20v1.0//EN%0ABEGIN%3AVEVENT%0AUID%3Ainfo@jungledragon.com%0ADTSTAMP%3A20140321T153043Z%0AATTENDEE%3BCN%3DMy%20Self%20%3BRSVP%3DFALSE%0ACATEGORIES%3AAPPOINTMENT%0ADTSTART%3A20140321T153043Z%0ADTEND%3A%0ALOCATION%3A5384%20DA%20Heesch%2C%20The%20Netherlands%0ASUMMARY%3AJungleDragon%20Daylight%20Event%0ADESCRIPTION%3AHey%20you%21%20%20%20%5Cn%20%5Cn%20%20At%20this%20time%20in%20your%20calendar%20light%20conditions%20are%20great%20for%20the%20location%20you%20selected%3A%5Cn%20%5Cnhttp%3A//www.ignore.org/apps/jd3/daylight%23date%3D1392996643000%26lat%3D51.73171%26long%3D5.527827000000002%5Cn%5CnHappy%20shooting%2C%20and%20be%20sure%20to%20share%20your%20wildlife%20photos%20back%20to%20http%3A//www.jungledragon.com%5CnCheers%2C%5CnThe%20JungleDragon%20Team%0AEND%3AVEVENT%0AEND%3AVCALENDAR

Next, the new tab is blank and nothing happens.接下来,新选项卡是空白的,什么也没有发生。 I'm not sure whether there is a syntax mistake in my .ics, but given that it works for Chrome and Firefox, I don't believe so.我不确定我的 .ics 中是否存在语法错误,但鉴于它适用于 Chrome 和 Firefox,我不这么认为。

Any thoughts?有什么想法吗?

Edit, extra info: If I manually open a downloaded .ics file with the exact same content, it does work also in IE and Opera.编辑,额外信息:如果我手动打开下载的 .ics 文件,内容完全相同,它也可以在 IE 和 Opera 中工作。 Something must be wrong with the way I open it using window.open?我使用window.open打开它的方式一定有问题吗?

Answering my own question:回答我自己的问题:

The problem was not in the .ics output itself, rather it was in IE and Opera not treating the js-generated output as a file to download.问题不在于 .ics 输出本身,而在于 IE 和 Opera 没有将 js 生成的输出视为要下载的文件。 To enforce such a download, is only possible from a server-side script.要强制执行此类下载,只能通过服务器端脚本进行。

I ended up recoding my logic to output the .ics file on the server-side, and by enforcing these headers:我最终重新编码了我的逻辑以在服务器端输出 .ics 文件,并通过强制执行这些标头:

header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename=cal.ics');

It was a painful restructuring, but now it works across browsers.这是一个痛苦的重组,但现在它可以跨浏览器工作。

It appears there is a way to do this without using a server-side script.似乎有一种方法可以在不使用服务器端脚本的情况下执行此操作。 I answered a similar Stack Overflow question when I found this snippet that worked for me in the github issues for react-add-to-calendar :当我在react-add-to-calendargithub 问题中发现这个对我 有用的代码段时,我回答了一个类似的 Stack Overflow 问题

var blob = new Blob([icsMSG], { type: 'text/calendar;charset=utf-8' });
window.navigator.msSaveOrOpenBlob(blob, 'download.ics');

This is working for me in Internet Explorer 11 without having to use a server to download the file.这在 Internet Explorer 11 中对我有用,而无需使用服务器下载文件。

简化的解决方案可能只是使用链接内的下载属性来设置文件名

<a class="icon-ical" href="data:text/calendar;charset=utf8...." download="cal.ics">iCal Calendar</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM