代码之家  ›  专栏  ›  技术社区  ›  Luke

Fine Uploader在Facebook iframe中失败

  •  0
  • Luke  · 技术社区  · 12 年前

    我已经建立了一个需要一些图像上传功能的Facebook应用程序,为了实现它,我使用了Fine Uploader。

    Facebook应用程序本身是用WordPress构建的,一切都很好。最终,WordPress网站(即应用程序)将以iframe的形式出现在Facebook上,事情变得越来越有趣。

    当我在本地机器上测试应用程序时,它可以工作(所有浏览器)。当我在我的暂存环境中测试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.
    ) 
    
    2 回复  |  直到 12 年前
        1
  •  0
  •   Mark Feltner    11 年前

    正如我所怀疑的那样,问题是父窗口的域与包含响应的iframe的域不匹配。这是一种安全违规行为,并且没有简单的方法可以访问此iframe的内容,因为它位于不同的域上。浏览器禁止这种访问。绕过这一点有点棘手,但Fine Uploader提供了一种方法。

    您需要在Fine Uploader中启用CORS功能。这可能是你最好的选择,这应该可以解决你的问题。Fine Uploader最近增加了对跨域请求的支持(3.3版)。这在涉及iframe的IE中特别有用。从本质上讲,您将配置响应以导入一个javascript文件,该文件将向包含响应的父窗口发布一条消息。这就是Fine Uploader克服跨域问题的方法。我写了 a detailed blog post on CORS support 在Fine Uploader中,以及如何启用它并在服务器端代码中正确处理Fine Upload发送的跨域请求。

    如果你阅读了这篇文章并遵循服务器端的说明,你似乎应该没事了。

    请注意,在您的情况下,这似乎只是IE9及更高版本中需要克服的问题。以下是您需要做的高级总结:

    1. 在Fine Uploader(客户端)中启用CORS支持。
    2. 服务器端:通过查看请求上的X-Requested-With标头来识别非XHR上传请求。
    3. 如果请求不是通过XHR发送的,则返回一个内容类型为“text/html”的响应,该响应以 <script> 标记,该标记从已知位置(任何位置)导入“iframe.xss.response.js”文件。在响应中的脚本标记之后,包括响应的正常有效JSON部分。

    希望这能有所帮助。

        2
  •  0
  •   George    11 年前

    只是为了在@Ray的回答中添加 不同的场景 从而 iframe属于同一个域 ,但相同 SEC7111: HTTPS security is compromised by res://ieframe.dll 仍然在https环境中接收:

    对于Apache,HTTP服务器

    在Apache Web服务器httpd.conf文件中添加/更改以下行

    Header always append X-Frame-Options SAMEORIGIN
    

    确保未将其设置为 DENY . 重新启动web服务器

    还要检查响应标头,以查看是否反映了上述更改

    推荐文章