Fine Uploader не работает в iframe Facebook

Я создал приложение Facebook, для которого требуются некоторые функции загрузки изображений, и для его реализации я использую Fine Uploader.

Само приложение Facebook построено на WordPress, и все работает нормально. В конце концов веб-сайт WordPress (который является приложением) будет жить на Facebook в iframe, и именно здесь все становится интереснее.

Когда я тестирую приложение на своем локальном компьютере, оно работает (все браузеры). Когда я тестирую приложение вне iframe в своей тестовой среде, оно также работает (все браузеры). Однако, когда я тестирую приложение на тестовой странице в Facebook (iframe), загрузка изображения не выполняется, только в IE.

Для справки я покажу свой серверный и клиентский код:

public static function upload_receiver()
{
    $uploader = new qqFileUploader();
    $uploader->allowedExtensions = array("jpg", "jpeg");
    $uploader->sizeLimit = 2024 * 1024;

    $wp_upload_dir = wp_upload_dir();
    $wp_upload_url = $wp_upload_dir['baseurl'];
    $wp_upload_base = $wp_upload_dir['basedir'];

    $upload_dir = $wp_upload_base;
    $upload_filename = md5(mt_rand())/*.'_'.$uploader->getName()*/.".jpg";

    $result = $uploader->handleUpload( $upload_dir, $upload_filename );

    // Create the WordPress image thumbs.
    $img_target = "{$upload_dir}/{$upload_filename}";

    $wp_filetype = wp_check_filetype( $img_target );

    $attachment_data = array(
        'post_mime_type' => $wp_filetype['type'], 
        'guid' => $img_target,
        'post_title' => preg_replace('/\.[^.]+$/', '', $upload_filename ),
        'post_name' => preg_replace('/\.[^.]+$/', '', $upload_filename ),
        'post_content' => '',
        'post_status' => 'inherit',
    );

    $attachment_id = wp_insert_attachment( $attachment_data, $img_target );

    $meta = wp_generate_attachment_metadata($attachment_id, $img_target);

    wp_update_attachment_metadata($attachment_id, $meta);   

    $result['attachmentId'] = $attachment_id;
    $result['imageUrl'] = htmlspecialchars( get_image_url_from_attachment_id($attachment_id, "thumb-small") );

    header("Content-Type: text/plain");
    echo json_encode( $result );

    die();
}

И клиент:

var el = $('#upload');
var el_img = el.find('span');

el.fineUploader( {
    uploaderType: 'basic',
    button: el,
    multiple: false,
    request: {
        endpoint: '<?php echo site_url("/wp-admin/admin-ajax.php") ?>',
        params: {
            action: 'upload_receiver'           
        }
    },
    validation: {
        allowedExtensions: ['jpeg', 'jpg']
    },
    debug: false
} ).on('upload', function(event, id, fileName, response) {
    $('.loader').show();
    $('.upload_button_container').hide();

} ).on('complete', function(event, id, fileName, response) {

    // ONLY IN IE "RESPONSE.SUCCESS" IS FALSE IN AN FB IFRAME. ALL OTHER
    // TIMES "RESPONSE.SUCCESS" IS TRUE AND ALL PROPERTIES CREATED ON THE
    // SERVER EXIST.

    $('.loader').hide();
    $('.upload_button_container').show();

    if( response.error )
    {
        alert( response.error );
        return;
    }

    // Display image coming in from the result.
    $(".img_upload_container img").attr('src', response.imageUrl).show();

    // Store the WordPress attachment Id for form submission.
    $("form input[name=bc_attachment_id]").val( response.attachmentId );
});

Последние несколько часов я ломал голову над этим, и у меня закончились идеи о том, что может быть причиной этой проблемы.

ИЗМЕНИТЬ:

Вывод консоли IE9:

LOG: [FineUploader] Processing 1 files or inputs... 
LOG: [FineUploader] Sending upload request for 0 
SEC7111: HTTPS security is compromised by res://ieframe.dll/forbidframing.htm 
SEC7111: HTTPS security is compromised by res://ieframe.dll/ErrorPageTemplate.css 
SEC7111: HTTPS security is compromised by res://ieframe.dll/errorPageStrings.js 
SEC7111: HTTPS security is compromised by res://ieframe.dll/httpErrorPagesScripts.js 
SEC7111: HTTPS security is compromised by res://ieframe.dll/red_x.png 
SEC7111: HTTPS security is compromised by res://ieframe.dll/bullet.png 
SEC7111: HTTPS security is compromised by res://ieframe.dll/background_gradient.jpg 
LOG: [FineUploader] Received response for 0 
[FineUploader] Error when attempting to access iframe during handling of upload response (Error: Access is denied.
) 
LOG: [FineUploader] iframe loaded 
[FineUploader] Error when attempting to parse form upload response (Error: Access is denied.
) 

person Luke    schedule 20.04.2013    source источник
comment
Для начала, можете ли вы установить для параметра отладки значение true и опубликовать содержимое консоли инструментов разработчика, т.е. при воспроизведении ошибки? У меня есть несколько мыслей о том, что может быть причиной этого, но я хотел бы посмотреть, смогу ли я получить дополнительную информацию.   -  person Ray Nicholus    schedule 20.04.2013
comment
Привет. Спасибо за это. Я добавил вывод отладки из IE9.   -  person Luke    schedule 20.04.2013
comment
И еще, можете ли вы проверить document.domain страницы и сравнить его с доменом сервера, обрабатывающего запрос? Сообщения журнала указывают, что содержимое iframe (содержащее ответ) недоступно из-за разных доменов.   -  person Ray Nicholus    schedule 20.04.2013
comment
Привет. Спасибо за это. Как проверить домен документа страницы?   -  person Luke    schedule 20.04.2013


Ответы (2)


Как я и подозревал, проблема в том, что домен родительского окна не совпадает с доменом iframe, содержащего ответ. Это нарушение безопасности, и нет простого способа получить доступ к содержимому этого iframe, поскольку он находится в другом домене. Такой доступ запрещен браузером. Это немного сложно обойти, но Fine Uploader предоставляет способ.

Вам нужно будет включить функцию CORS в Fine Uploader. Это, вероятно, ваш лучший вариант, и это должно решить вашу проблему. Fine Uploader недавно добавил поддержку междоменных запросов (версия 3.3). Это особенно полезно в IE, где задействованы iframe. По сути, вы настроите свой ответ для импорта файла javascript, который отправит сообщение в родительское окно, содержащее ваш ответ. Вот как Fine Uploader решает проблему междоменного доступа. Я написал подробный пост в блоге о поддержке CORS в Fine Uploader и как его включить и правильно обрабатывать междоменные запросы, отправленные Fine Uploader, в коде на стороне сервера.

Если вы прочитаете сообщение и будете следовать инструкциям на стороне сервера, похоже, у вас все будет в порядке.

Обратите внимание, что в вашем случае это проблема, которую вам нужно решить только в IE9 и старше. Вот краткое изложение того, что вам нужно сделать:

  1. Включите поддержку CORS в Fine Uploader (на стороне клиента).
  2. На стороне сервера: идентифицируйте запросы на загрузку, отличные от XHR, по заголовку X-Requested-With в запросе.
  3. Если запрос не был отправлен через XHR, верните ответ с типом содержимого «text/html», который начинается с тега <script>, который импортирует файл «iframe.xss.response.js» из известного места (где угодно). ). После тега script в своем ответе включите обычную допустимую часть ответа JSON.

Надеюсь это поможет.

person Ray Nicholus    schedule 20.04.2013

Просто добавим к ответу @Ray в другом сценарии, когда iframe относится к тому же домену, но тот же SEC7111: HTTPS security is compromised by res://ieframe.dll по-прежнему принимается в среде https:

Для Apache, HTTP-сервер

Добавьте/измените следующую строку в файле httpd.conf веб-сервера Apache.

Header always append X-Frame-Options SAMEORIGIN

Убедитесь, что он не установлен на DENY. Перезапустите веб-сервер

Также проверьте заголовок ответа, чтобы увидеть, как отражено указанное выше изменение.

person George    schedule 25.04.2014
comment
Обратитесь к тому, что я сказал выше жирным шрифтом, для другого сценария. Это помогло мне решить мою проблему, которая очень похожа на описанную выше (точные ошибки), и я просто предлагаю помощь тем, кто в ней нуждается. Пока я вижу, что это добавляет ценности, не имеет значения, если вы проголосуете против моего ответа. - person George; 25.04.2014
comment
Извините, но описанный вами сценарий не относится к вопросу, за исключением того факта, что и вы, и вопрос упоминаете фреймы. Заголовок X-Frame-Options не имеет значения, когда вы говорите о доступе к отображаемому контенту в контекстах просмотра, которые пересекают домены. Это то, что здесь пытаются решить. Ваш ответ касается отображения контента, а не доступа к нему. - person Ray Nicholus; 25.04.2014
comment
SEC7111: HTTPS security is compromised by res://ieframe.dll для отображения. [FineUploader] Error when attempting to access iframe для доступа. - person George; 26.04.2014
comment
[FineUploader] Ошибка при попытке доступа к iframe во время обработки ответа на загрузку (Ошибка: доступ запрещен. ) LOG: [FineUploader] iframe загружен [FineUploader] Ошибка при попытке проанализировать ответ на загрузку формы (Ошибка: доступ запрещен. ) - person Ray Nicholus; 26.04.2014