我正在为体育联盟网站构建一个简单的Google Maps / Calendar工具。它会根据单击的地图标记在iframe中加载多个日历之一。这在台式机上效果很好,尽管在Firefox中确实会在控制台中引起一系列警告:
Content Security Policy: The page’s settings observed the
loading of a resource at inline (“script-src”). A CSP report is being sent.
在移动设备上,默认(主)日历会在页面加载时正确加载。点按地图标记时,iframe的内容会消失,但不会重新加载新日历。有没有一种方法可以从移动设备的外部源强制重新加载iframe?我在Chrome,Safari和Firefox浏览器中的iPhone XR,iPhone 8和Samsung S7上遇到了相同的错误。
我尝试使用Location.reload方法强制重新加载。这不起作用,因为它要求iframe来自同一来源。我还尝试了在堆栈溢出中找到的以下代码片段,以解决相关问题:
document.getElementById('cal').src += '';
其中#cal是iframe本身的ID。这不会导致功能更改。
最后,我使用文档的中的meta标记对Content Security Policy进行了修改。通过包含Google的域(googleapis.com,google.com等),我可以使某些CSP错误停止,但是由于意外阻止其他网站资源而导致同等数量的错误(我不知道我是什么)使用此标签。)标签当前看起来像这样:
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' fonts.googleapis.com 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' maps.googleapis.com fonts.googleapis.com calendar.google.com; frame-src https://calendar.google.com https://accounts.google.com">
我知道这是错误的,不安全的,凌乱的,以及其他所有内容,但我只是想使某些事情起作用,所以我可以向后走,解决问题的根源。
用于创建此地图/日历工具的相关代码如下:
<div id="container">
<div id="map"></div>
<div id="capture"><iframe src="https://calendar.google.com/calendar/embed?mode=AGENDA&height=500&wkst=1&bgcolor=%23FFFFFF&src=example.com_mgj0i3q12ang1as82p8ggf3fuc@group.calendar.google.com&color=%23691426&ctz=America%2FVancouver" style="border-width:0" width="500" height="500" frameborder="0" scrolling="no"></iframe></div>
</div>
<script type="text/javascript">
//begin by building map. change element ID and vars as needed.
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(49.876837, -119.461071),
zoom: 11,
mapTypeId: 'roadmap',
styles: [{ /*removed for brevity */ }]
}
]
});
/* set location marker variables within this array of arrays (name, lat, long, calID). Called by the marker constructor based in array index */
markers = [
['Parkinson Sports Fields', 49.88264, -119.46045, 'example.com_ee05ufe760mls53v7i8juk21hc@group.calendar.google.com'],
['Rutland Sports Fields', 49.89953, -119.38019, 'example.com_kkp2n6a430b5hp1nsneins9rko@group.calendar.google.com'],
['Mission Sports Fields', 49.83979, -119.47623, 'example.com_9b03spb4qm2alg3g3kqhn7sols@group.calendar.google.com'],
['Rosewood Sports Field', 49.87567, -119.56956, 'example.com_d2837h2fnv0f5aon52hfisuev8@group.calendar.google.com'],
['Shannon Woods Sports Field', 49.8669, -119.60595, 'example.com_dg3t7cph204esc98qeq81egk4s@group.calendar.google.com']
];
var marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
title: markers[i][0],
label: {
text: markers[i][0],
fontSize: "12px",
fontWeight: "bold"
},
map: map,
icon: markerIcon,
calURL: '<iframe id="cal" src="https://calendar.google.com/calendar/embed?mode=AGENDA&height=500&wkst=1&bgcolor=%23FFFFFF&src=' + markers[i][3] + '&color=%23691426&ctz=America%2FVancouver" style="border-width:0" width="500" height="500" frameborder="0" scrolling="no"></iframe>'
});
//Attempts to smoothly zoom on marker click. Currently buggy; exploring resolutions.
google.maps.event.addListener(marker, 'click', function() {
map.setCenter(this.getPosition());
for (z = 1; z < 16; z++) {
map.setZoom(z)
}
/* this section replaces the iframe in the schedule div with the individual field's calendar. */
var calsec = document.getElementById('capture');
calsec.innerHTML = this.calURL;
document.getElementById('cal').src += '';
});
}
脚本继续进行,但是本节包含相关部分:标记构造函数,构造函数数组和onclick函数,以放大所选字段并交换事件日历。
答案 0 :(得分:0)
正如@ducmai所评论的那样,答案非常简单。通过添加行
calsec.innerHTML = null;
在插入新的日历iframe之前,日历加载会稍慢(刷新会延迟1秒左右),但现在会在所有设备上显示!
此外,我需要将每个日历设置为公开。大多数是,但是由于我忘记正确设置日历,一些返回了X框架错误。