Jestem autorem printThis, wtyczki jquery do drukowania.jquery - odmowa dostępu iframe w IE na niektórych stronach
https://github.com/jasonday/printThis
Mam użytkownika, który przyniósł aż problem, że nie udało mi się złamać i niestety, nie jestem w stanie udostępnić stronę (dotyczy Privacy).
Na stronie użytkownika problem występuje na niektórych stronach w IE, ale nie na innych. Wydruk nie powiódł się, ponieważ element iframe pozostaje pusty.
Błąd w IE jest w jQuery:
contents: function (a) {
return f.nodeName(a,
"iframe") ? a.contentDocument || a.contentWindow.document : f.makeArray(a.childNodes)
}
Korzystanie rejestrowanie, udało mi się ustalić, to było w przypadku braku wokół tej linii:
var $doc = $("#" + strFrameName).contents();
Ale znowu, to dzieje się tylko na niektórych stronach i nie mogłem odtworzyć w żadnym przypadku poza witryną tego użytkownika.
Moje pytanie: czy jest tu lepsze podejście? lub sposób na uczynienie obiektu $doc
bardziej kuloodpornym?
// -----------------------------------------------------------------------
// printThis v1.1
// Printing plug-in for jQuery
//
// Resources (based on) :
// jPrintArea: http://plugins.jquery.com/project/jPrintArea
// jqPrint: https://github.com/permanenttourist/jquery.jqprint
// Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
//
// Dual licensed under the MIT and GPL licenses:
// http://www.opensource.org/licenses/mit-license.php
// http://www.gnu.org/licenses/gpl.html
//
// (c) Jason Day 2012
//
// Usage:
//
// $("#mySelector").printThis({
// debug: false, //show the iframe for debugging
// importCSS: true, // import page CSS
// printContainer: true, // grab outer container as well as the contents of the selector
// loadCSS: "path/to/my.css" //path to additional css file
// });
//
// Notes:
// - the loadCSS option does not need @media print
//------------------------------------------------------------------------
(function($) {
var opt;
$.fn.printThis = function (options) {
opt = $.extend({}, $.fn.printThis.defaults, options);
var $element = (this instanceof jQuery) ? this : $(this);
// if Opera, open a new tab
if ($.browser.opera)
{
var tab = window.open("","Print Preview");
tab.document.open();
}
// add dynamic iframe to DOM
else
{
var strFrameName = ("printThis-" + (new Date()).getTime());
var $iframe = $("<iframe id='" + strFrameName +"' src='about:blank'/>");
if (!opt.debug) { $iframe.css({ position: "absolute", width: "0px", height: "0px", left: "-600px", top: "-600px" }); }
$iframe.appendTo("body");
}
// allow iframe to fully render before action
setTimeout (function() {
if ($.browser.opera)
{
var $doc = tab.document;
} else
{
var $doc = $("#" + strFrameName).contents();
}
// import page css
if (opt.importCSS)
{
$("link[rel=stylesheet]").each(function(){
var href = $(this).attr('href');
if(href){
var media = $(this).attr('media') || 'all';
$doc.find("head").append("<link type='text/css' rel='stylesheet' href='" + href + "' media='"+media+"'>");
}
});
}
// add another stylesheet
if (opt.loadCSS)
{
$doc.find("head").append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
}
//add title of the page
if (opt.titlePage)
{
$doc.find("head").append('<title>'+opt.titlePage+'</title>');
}
//grab outer container
if (opt.printContainer) { $doc.find("body").append($element.outer()); }
else { $element.each(function() { $doc.find("body").append($(this).html()); }); }
//$doc.close();
// print
($.browser.opera ? tab : $iframe[0].contentWindow).focus();
setTimeout(function() { ($.browser.opera ? tab : $iframe[0].contentWindow).print(); if (tab) { tab.close(); } }, 1000);
//removed iframe after 60 seconds
setTimeout(
function(){
$iframe.remove();
},
(60 * 1000)
);
}, 333);
}
$.fn.printThis.defaults = {
debug: false, //show the iframe for debugging
importCSS: true, // import page CSS
printContainer: true, // grab outer container as well as the contents of the selector
loadCSS: "", //path to additional css file
titlePage: "" //add title to print page
};
jQuery.fn.outer = function() {
return $($('<div></div>').html(this.clone())).html();
}
})(jQuery);
UPDATE
Issue aby ze względu na document.domain
Ten typ stronę document.domain
zestaw i IE nie dziedziczy document.domain
od rodzica.
Aby naprawić tę część, zmieniono tworzenie elementu iframe na standardowy javascript i ustawiono źródło do napisania document.domain
w przypadku tworzenia elementu iframe.
var printI= document.createElement('iframe');
printI.name = "printIframe";
printI.id = strFrameName;
document.body.appendChild(printI);
printI.src = "javascript:document.write('<head><script>document.domain=\"mydomain.com\";</script></head><body></body>')";
var $iframe = $("#" + strFrameName);
To rozwiązuje problem odmowy dostępu, ale teraz ramka nie zostanie wydrukowana. Próbowałem wielu różnych metod uzyskiwania dostępu do obiektu, jednak żaden z nich nie działa.
A) w jaki sposób uzyskać dostęp do klatki w tym scenariuszu (próbowałem większość metod przedstawiono na SO), aby uzyskać IE rozpoznać i wydrukować
lub
B) może ktoś pomyśleć lepszy sposób uzyskania document.domain w iframe podczas tworzenia z jQuery? (nie może być później, ponieważ pojawi się problem odmowy dostępu)
Czy wszystkich stron w tej samej domenie/subdomenie? – Christophe
@ Christophe - tak. Wszystkie strony należą do tej samej domeny. Wydruk nie działa specjalnie na jednym typie strony, ale działa na wszystkich innych. – Jason
Może być pomocna: http://stackoverflow.com/questions/364952/jquery-javascript-accessing-contents-of-an-iframe – JSuar