我尝试访问网页中包含pdf查看器的iframe的contentDocument时出错。控制台抱怨跨源框架访问,虽然这对我来说是一个相当新的话题,但我不知道为什么框架有一个不同的域,如果它们都是我的并在我的主页面内,也不知道如何解决它
app-046a31d445.js:57510错误:无法阅读' contentDocument' 属性来自' HTMLIFrameElement':阻止了一个包含原点的框架 " https://mockupdomain.com"从访问跨源框架。
代码是angularJS指令,超简化就是这样:
<div>
<ng-form name="pdfform"">
<!-- some inputs -->
<button ng-click="ctrl.showIframe()"></button>
</ng-form>
<iframe type="text/html"></iframe>
</div>
(function () {
'use strict';
angular
.module('pdf')
.directive('pdfViewer', pdfViewer);
function pdfViewer() {
return {
restrict: 'EA',
scope: {
//variables
},
templateUrl: 'directives/pdf-viewer.tpl.html',
transclude: true,
controllerAs: 'ctrl',
controller: function ($scope, $sce, $location) {
var vm = this;
$scope.vm = vm;
/*var parts = $location.$$host.split('.');
var upperleveldomain = parts.slice(-2).join('.');
document.domain = upperleveldomain;*/
document.domain = $location.host();
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
},
link: function (scope, element, attrs, form) {
scope.vm.showIframe = showIframe;
var iframe = angular.element('iframe');
function showIframe() {
scope.errors = [];
iframe.attr('src', 'https://mockupdomain.com/api/getfile?format=pdf');
}
iframe.on('load', function() {
//some code
});
iframe.bind('load', function (event) {
if (angular.isDefined(iframe[0].innerHTML)) {
var head = iframe[0].contentDocument.head; // <--- this is the line that produces the error.
var status = head.querySelector('meta[name=status]').content;
if (status >= 300) {
scope.errorMsg = head.querySelector('meta[name=message]').content;
scope.error = head.querySelector('meta[name=validations]').content;
}
}
});
scope.$emit('pdfViewerReady');
}
};
}
}());
行var head = iframe[0].contentDocument.head;
产生错误,因为contentDocument
无法访问,因此null
或undefined
。我不知道这背景有什么影响所以我很抱歉,如果我做了一些愚蠢的陈述。跨域框架访问对我来说是一个新主题。我在另一个主题(SecurityError: Blocked a frame with origin from accessing a cross-origin frame)上找到了这个答案,但我仍然不知道如何处理给定的解决方法。
同样评论代码拆分$location.$$host
是一种解决方法,允许iframe在Firefox和Chrome中显示(否则它不能与Firefox一起使用)。但是它对跨源错误有一些改变效果,因为它曾经在api调用返回成功时出现,但是通过拆分$location.$$host
代码,当api调用由于我们的应用程序返回400错误代码时会产生错误权限系统。这只会让我更加困惑。