我正在尝试在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日志中
我做错了什么?
答案 0 :(得分:3)
要下载文件,您必须使用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
);
然后修改AJAX返回的“成功”部分,如下所示:
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()
。
答案 1 :(得分:0)
@肖恩-金博尔,
您可能希望扩展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';
为此,我还建议您使用MODX的index.php主文件作为AJAX的连接器,这样处理器中的$modx
对象也会继承访问权限。
http://www.virtudraft.com/blog/ajaxs-connector-file-using-modxs-main-index.php.html