Подтвердить что ты не робот

Как настроить пользовательские заголовки HTTP при изменении iframe src?

Есть ли способ добавить пользовательский HTTP-заголовок в запрос, выполняемый <iframe> при смене источника (src) с помощью javascript?

4b9b3361

Ответ 1

Вы можете получить результаты запроса ajax, для которого пользовательские заголовки должны быть установлены как содержимое iframe, например:

$.ajax({
    type: "GET", 
    url: "https://app.icontact.com/icp/a/",
    contentType: "application/json",
    beforeSend: function(xhr, settings){
            xhr.setRequestHeader("some_custom_header", "foo");},
    success: function(data){
        $("#output_iframe_id").attr('src',"data:text/html;charset=utf-8," + escape(data))
    }
});

Предполагается, что iframe указывает на кросс-домен src. Это проще, если все находится в одном домене.

Изменить: Возможно, попробуйте это изменение.

$.ajax({
    type: "GET", 
    url: "https://app.icontact.com/icp/a/",
    contentType: "application/json",
    beforeSend: function(xhr, settings){
            xhr.setRequestHeader("some_custom_header", "foo");},
    success: function(data){
        $("#output_iframe_id").attr('src',"/")
        $("#output_iframe_id").contents().find('html').html(data); 
    }
});

Ответ 2

Работает следующий код. Это модификация кода предоставленного Мэтью Грейвсом, измененный для использования атрибута srcdoc для решения проблемы ссылок CSS и JavaScript, которые не были запущены. К сожалению, он работает только в Chrome.

 $.ajax({
        type: "GET", 
        url: "https://app.icontact.com/icp/a/",
        contentType: "application/json",
        beforeSend: function(xhr, settings){
                xhr.setRequestHeader("some_custom_header", "foo");},
        success: function(data){
            $("#output_iframe_id").attr('srcdoc',data)
        }
    });

Изменить. Наконец, я решил проблему блокировки блоков кросс-браузера, переназначив их в iframe в функции document.ready:

$(document).ready(function () {
    var doc = $(document);
    if (frames.length > 0) {
        doc = frames[0].document;
        $(doc).find('script').each(function () {
            var script = document.createElement("script");
            if ($(this).attr("type") != null) script.type = $(this).attr("type");
            if ($(this).attr("src") != null) script.src = $(this).attr("src");
            script.text = $(this).html();
            $(doc).find('head')[0].appendChild(script);
            $(this).remove();
        });
    }
});

Ответ 3

В итоге я перешел к подходу, предложенному другими ответами здесь, которые используют ajax для получения строки html, а затем непосредственно устанавливают содержимое iFrame.

Однако я использовал подход, опубликованный в этом ответе, чтобы фактически установить содержимое iFrame, так как я нашел, что он хорошо работал на кросс-платформе почти со всеми устройствами Я мог бы раскопать.

Протестировано - успешно:

  • Chrome 54 (рабочий стол) ^
  • Firefox 49 (рабочий стол) ^
  • IE 11 (рабочий стол) ^
  • IE 10 (рабочий стол) в режиме эмуляции ^
  • Safari/Chrome на iOS 8 (ipad)
  • Chrome на Android 6 (нексусный телефон)
  • Edge on Lumia 950 (Win 10 Phone)

^ подтвердил, что связанные css и js в содержимом работают правильно (другие не тестировались)

Протестировано - неудачно:

  • IE 9 (рабочий стол) в режиме эмуляции
  • Safari/Chrome на iOS 7 (iPhone)

Таким образом, их объединение дает что-то вроде этого (Примечание: я действительно не запускаю этот точный код):

$.ajax({
    type: "GET", 
    url: "https://yourdomain.com/gethtml",
    beforeSend: function(xhr) {
        xhr.setRequestHeader("yourheader", "value");
    },
    success: function(data) {
        var iframeDoc = document.querySelector('#myiframe').contentWindow.document;
        iframeDoc.open('text/html', 'replace');
        iframeDoc.write(data);
        iframeDoc.close();
    }
});

Здесь приведен пример установки iFrame содержимого в этом JS-бине

Изменить: Здесь html часть

<iframe id="myiframe" src="about:blank"></iframe>

Изменить 2:

Вышеприведенное решение больше не работает в Firefox (50.1.0) по неизвестной причине. Используя решение в ответе , теперь я изменил код на приведенный ниже пример, который также кажется более надежным:

$.ajax({
    type: "GET", 
    url: "https://yourdomain.com/gethtml",
    beforeSend: function(xhr) {
        xhr.setRequestHeader("yourheader", "value");
    },
    success: function(data) {
        var iframe = document.getElementById('myiframe');
        iframe.contentWindow.contents = data;
        iframe.src = 'javascript:window["contents"]';
    }
});

Ответ 4

Вместо использования URI данных или установки содержимого в строку вы можете использовать URL.createObjectURL() и установить его как src iframe.

var xhr = new XMLHttpRequest();

xhr.open('GET', 'some.pdf');
xhr.onreadystatechange = handler;
xhr.responseType = 'blob';
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.send();

function handler() {
  if (this.readyState === this.DONE) {
    if (this.status === 200) {
      // this.response is a Blob, because we set responseType above
      var data_url = URL.createObjectURL(this.response);
      document.querySelector('#output-frame-id').src = data_url;
    } else {
      console.error('no pdf :(');
    }
  }
}

URL-адреса объектов довольно интересны. Они имеют форму blob:https://your.domain/1e8def13-3817-4eab-ad8a-160923995170. Вы можете открыть их на новой вкладке и увидеть ответ, и они будут отброшены, если контекст, создавший их, будет закрыт.

Вот полный пример: https://github.com/courajs/pdf-poc