Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用ajax执行将文件推送到浏览器的php函数?_Php_Jquery_Ajax_Modx - Fatal编程技术网

如何使用ajax执行将文件推送到浏览器的php函数?

如何使用ajax执行将文件推送到浏览器的php函数?,php,jquery,ajax,modx,Php,Jquery,Ajax,Modx,我试图在一个php类中编写一个方法,它将使用ajax执行一个php函数,将文件推回到浏览器 它似乎试图将文件写入modx日志,在那里得到大量二进制垃圾 方法如下: public function pushDocuments($formdata){ $data = $formdata['formdata']; $file = MODX_PROTECTED_STORAGE . $data['target']; $file_name = basename($file);

我试图在一个php类中编写一个方法,它将使用ajax执行一个php函数,将文件推回到浏览器

它似乎试图将文件写入modx日志,在那里得到大量二进制垃圾

方法如下:

public function pushDocuments($formdata){

    $data = $formdata['formdata'];

    $file = MODX_PROTECTED_STORAGE . $data['target'];

    $file_name = basename($file);

    if (file_exists($file)) {

        header("Content-Disposition: attachment; filename=\"$file_name\"");
        header("Content-Length: " . filesize($file));
        header("Content-Type: application/octet-stream;");
        readfile($file);

    };

    $output = array(

        'status' => 'success',
        'error_messages' => array(),
        'success_messages' => array(),

    );

    $output = $this->modx->toJSON($output);

    return $output;

}
下面是jquery:

$('.btn-get-document').click(function(){

    var target = $(this).attr('data-target');
    var postdata = {"snippet":"DataSync", "function":"pushDocuments", "target": target}; // data object ~ not json!!
    console.log('target = ' + target + postdata );

    $.ajax({
        type: "POST",
        url: "processors/processor.ajax.generic/",
        dataType  : "json",
        cache : false,
        data: postdata, // posting object, not json
        success: function(data){
            if(data.status == 'success'){
                console.log("SUCCESS status posting data");
            }else if(data.status == 'error'){
                console.log("error status posting data");
            }

        },
        error: function(data){
                console.log("FATAL: error posting data");
            }
    });
});
它正在运行脚本并在控制台中获得成功[因为我正在强制成功],但没有提示下载文件,二进制垃圾显示在modx日志中


我做错了什么?

要下载文件,必须使用JS重定向到文件的位置。您不能通过AJAX提取文件内容并指示浏览器将这些内容保存为文件

您需要在结构上更改设置。例如,您的PHP脚本可以验证要下载的文件是否存在,然后向JS发送链接以下载该文件。大概是这样的:

if ( file_exists( $file )) {
    $success_message = array(
        'file_url' => 'http://example.com/file/to/download.zip'
   );
}

$output = array(
    'status'           => 'success',
    'error_messages'   => array(),
    'success_messages' => $success_message
);
success: function( data ) {
    if ( data.status == 'success' ) {
        location.href = data.success_messages.file_url;
    } else if ( data.status == 'error' ) {
        console.log( 'error status posting data' );
    }
},
然后修改AJAX返回的“成功”部分,如下所示:

if ( file_exists( $file )) {
    $success_message = array(
        'file_url' => 'http://example.com/file/to/download.zip'
   );
}

$output = array(
    'status'           => 'success',
    'error_messages'   => array(),
    'success_messages' => $success_message
);
success: function( data ) {
    if ( data.status == 'success' ) {
        location.href = data.success_messages.file_url;
    } else if ( data.status == 'error' ) {
        console.log( 'error status posting data' );
    }
},
由于您指向的是一个文件,只要文件的内容配置设置为“附件”,浏览器窗口实际上就不会出现在任何地方。通常,如果您指向浏览器内部未处理的任何文件(如ZIP文件),就会发生这种情况。如果您想控制它,以便它下载所有文件(包括浏览器可能使用插件处理的内容),您可以指向另一个PHP脚本,该脚本将发送适当的头,然后发送文件(类似于您发送头的方式,并在示例中使用
readfile()
)。

@sean kimball

您可能希望扩展MODX的基于类的处理器:

它可以从任何媒体源进行下载,如果需要,还可以进行访问检查

其在管理者端的实现是:

回到您的案例,这些例子可能会给您带来一些想法

JS示例:

$.ajax({
    type: "POST",
    // read my note down below about connector file
    url: "assets/components/mypackage/connectors/web.php", 
    dataType  : "json",
    cache : false,
    data: {
        action: 'mypath/to/processor/classfile'
    }
    success: function(data){

    },
    error: function(data){
        console.log("FATAL: error posting data");
    }
});
处理器示例:

<?php

require_once MODX_CORE_PATH . 'model/modx/processors/browser/file/download.class.php';

class myDownloadProcessor extends modBrowserFileDownloadProcessor {
    // override things in here
}

return 'myDownloadProcessor';

问题不在于jquery请求接收的是响应,而不是父浏览器窗口吗?看起来您试图同时向浏览器发送json响应和文件。这是行不通的。或者只是将一个隐藏的表单发布到iframehmm,问题是这些文件位于一个不可通过web访问的目录中。我不能只是转发一个指向该文件的链接。但问题的根源似乎是我无法通过ajax响应推送文件。。。对吗?@SeanKimball,我回答的最后一句话将解决这个问题。创建一个PHP脚本,该脚本可以引用该文件(可以是文件名,但是您需要能够识别它)。让该脚本输出标题并使用
readfile()
发送数据。使用适当的标识符返回指向此PHP脚本的链接,而不是将指向文件的链接返回到AJAX。