Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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
Model view controller TYPO3 Extbase-如果用户未登录前端,下载文件将被剪切到40KB_Model View Controller_Typo3_Extbase_Typo3 6.2.x - Fatal编程技术网

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数据……如果具有活动的后端上下文,则会禁用缓存。因此,您必须检查插件操作设置,请参阅