Model view controller TYPO3 Extbase-如果用户未登录前端,下载文件将被剪切到40KB
我从我的同事那里创建了一个下载扩展的副本,它基本上是一个只提供后端下载文件的扩展 问题:Model view controller TYPO3 Extbase-如果用户未登录前端,下载文件将被剪切到40KB,model-view-controller,typo3,extbase,typo3-6.2.x,Model View Controller,Typo3,Extbase,Typo3 6.2.x,我从我的同事那里创建了一个下载扩展的副本,它基本上是一个只提供后端下载文件的扩展 问题: <ul> <li>0</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li>
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
如果我尝试下载一个文件,而扩展名只有在登录到后端后才能访问,那么它就可以正常工作
但是,如果我打开一个没有登录到后端的私有浏览器窗口,那么它总是会切断文件并只下载前40 KB。。。即使它通常是10MB。为什么文件被切断了
我可以完美地下载小文件(<40KB),而不会被剪掉。
注意:
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
在我编辑扩展之前,下载效果非常好,即使没有登录到后端!下载也是以同样的方式触发的
目前,我正在比较代码,但从逻辑上看,它看起来还可以,因为我没有做太多更改(添加了一个新模型,重命名了扩展和其他一些东西)
有人知道什么会导致这个问题吗
这是我的下载控制器中的相关部分,我首先通过传递文件的fid
获取文件的公共url,然后通过发送头触发下载
...
if ($this->request->hasArgument('fid')) {
$this->fid = $this->request->getArgument('fid');
}
if ($this->request->hasArgument('cid')) {
$this->cid = $this->request->getArgument('cid');
}
$fileobj = $this->fileRepository->findByUid($this->fid);
if ($fileobj->getFile() !== null) {
$downloadFilePath = $fileobj->getFile()->getOriginalResource()->getPublicUrl();
if (file_exists($downloadFilePath)) {
$fileCounter = (int)$fileobj->getCounter();
$fileobj->setCounter(++$fileCounter);
$oldChecksum = $fileobj->getChecksume();
$groesse = filesize($downloadFilePath);
if (isset($oldChecksum)) {
$checksum = sha1_file($downloadFilePath);
$fileobj->setChecksume($checksum);
}
// update fileobj
$this->fileRepository->update($fileobj);
// Unset fileobj before persists, otherwise there will be also changes
$this->persistenceManager->persistAll();
// If file exists, force download
$fileName = basename($downloadFilePath);
$this->response->setHeader('Content-Type', "application/force-download", TRUE);
$this->response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName, TRUE);
$this->response->setHeader('Content-Length', $groesse, TRUE);
@readfile($downloadFilePath);
$this->response->sendHeaders();
return true; //i can also delete this line, since it is never reached.
} else {
//send emails to everyone who is entered in the address list in the extension configuration.
$this->sendEmails('missing_file', $fileobj);
$this->redirect(
'list',
'Category',
NULL,
array(
'missing' => array(
'fileId' => $this->fid,
'category' => $this->cid
)
)
);
}
}
40KB的文件不包含任何不应该存在的内容,它只是被切断了。我通过逐行在文件中写入大量数字并下载来测试它,结果是:文件中只有几千个数字,而不是所有数字
我尝试了这两种方法,存储在FTP服务器上的文件和存储在user_upload中的文件,结果相同
在这里您可以看到40 KB的文件:
片段(如果链接断开):
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
现在该文件已完全下载,但该文件现在已从模板包装到html中。它在流体变量mainContent
内渲染
像这样:
...
<!--TYPO3SEARCH_begin-->
<div class="clearfix col-sm-{f:if(condition:'{data.backend_layout} == 4',then:'12',else:'9')} col-md-{f:if(condition:'{data.backend_layout} == 4',then:'9',else:'6')} col-lg-{f:if(condition:'{data.backend_layout} == 4',then:'10',else:'8')} mainContent">
<f:format.raw>{mainContent}</f:format.raw>
</div>
<!--TYPO3SEARCH_end-->
...
。。。
{mainContent}
...
越来越奇怪…我终于解决了这个问题。发送标题后,我只需执行
exit
或die
:
<li>3183</li>
<li>3184</li>
<li>3185</li>
<li>3186</li>
<li
@readfile($downloadFilePath);
$this->response->sendHeaders();
exit;
注意:如果您使用exit
或die
退出代码,则键入3个会话集,例如$GLOBALS['TSFE']->fe_user->setKey(“ses”,“token”,DownloadUtility::getToken(32))如果不登录后端,代码>将不再工作!使用$GLOBALS['TSFE']->fe_user->setAndSaveSessionData(“token”,DownloadUtility::getToken(32))代码>在这种情况下,如果不需要登录
现在,即使没有登录到前端,它也可以工作
但是我仍然不知道为什么在登录到后端时下载没有被切断,即使退出声明丢失了。这非常奇怪,我们没有任何解释。readfile
直接将数据写入在响应对象周围工作的输出缓冲区。您可以这样做,但必须确保在发送文件内容之前发送头。最后,必须停止系统的进一步处理和输出。更好的方法是对头和内容严格使用响应对象…@OliverHader+1。file_get_contents读取整个文件并将其分配给变量。删除输出缓冲区命令,改为使用readfile,它通过Web服务器启动流输出。不幸的是,这意味着您必须在下载之前自己传输http头并退出脚本执行,而不是返回Extbases AbstractActionController。一种更简洁的方法是连接一个视图来替换传输文件的TemplateView。这里的exit
调用(这就是我在前面的注释中所说的“停止执行”)非常重要。因为TYPO3即使在控制器完成后也会继续处理。在这里,额外的头、输出和调试代码段(例如,如果使用Install Toll中定义的开发上下文)被添加到输出中。然后,这种混合会使内容无效,因为内容更长或包含混合的二进制和HTML数据……如果具有活动的后端上下文,则会禁用缓存。因此,您必须检查插件操作设置,请参阅