最近在做公司的一个内部管理系统,因为自己php不熟,公司又没有asp.net的环境,所以自己最后居然用js+CGI的模式,运行速度倒是飞快了,编码却麻烦的要死……罪过啊,罪过,又不是外网……
废话不多说了,有一个问题就是要在调用我的CGI的时候,返回一个文件下载对话框。
好吧,在网上搜了一下,实际上只是http头里面有这样一段就可以了:

Content-Disposition:   attachment;   filename= %s\r\n\r\n

找到了php版如下:

$old_name = “E:\a.doc”;
$file_name = “新文件名.doc”;
if (!file_exists($old_name)) { //检查文件是否存在
    echo “文件找不到”;
    exit;
} else {
    $file = fopen($old_name, “r”); //   打开文件
    //   输入文件标签
    Header(“Content-type:   application/octet-stream”);
    Header(“Accept-Ranges:   bytes”);
    Header(“Accept-Length:   “.filesize($old_name));
    Header(“Content-Disposition:   attachment;   filename=”.$file_name);
    //   输出文件内容
    echo fread($file, filesize($old_name));
    fclose($file);
    exit;
}
}

C#版如下:

public static void ToDownload(string serverfilpath,string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = “application/octet-stream”;
    HttpContext.Current.Response.AddHeader(“Content-Disposition”, “attachment; filename=\”” + UTF_FileName(filename) + “\”;”);
    ////attachment — 作为附件下载
    ////inline — 在线打开
    HttpContext.Current.Response.AddHeader(“Content-Length”, fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}
public static void ToOpen(string serverfilpath, string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = “application/octet-stream”;
    HttpContext.Current.Response.AddHeader(“Content-Disposition”, “inline; filename=\”” + UTF_FileName(filename) + “\”;”);
    HttpContext.Current.Response.AddHeader(“Content-Length”, fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}
private static string UTF_FileName(string filename)
{
    return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
}

所以其实最后的C++版也就比较明显了(我没有读本地文件,因为内容直接在一个string的buff里):

printf(“Content-type:   application/octet-stream\r\n”);
printf(“Content-Length: %u\r\n”,ccpp.filecontent.size());
printf(“Content-Disposition:   attachment;   filename= %s\r\n\r\n”,filename.c_str());
const char *ptr = ccpp.filecontent.c_str();
for(unsigned int i =0 ;i < ccpp.filecontent.size();++i)
{
    putchar(*(ptr+i));
}

先解释一下,由于webserver会将标准输出重定向,所以用printf实际就是返回到了浏览器端,至于用putchar是因为二进制的原因。
在这里还碰到了一个诡异的问题,即用

write(1,ptr,ccpp.filename.size());

会直接500 error,不知道为什么……

配合jquery实现异步加载页面元素

最近在做系统的时候,遇到了一个瓶颈,即在列出所有素材的列表列表的时候,由于素材都是swf或者jpg,结果几百个文件的时候,就会导致页面加载极慢,老大说让...

阅读全文

O3D基础教程1 简明介绍和程序框架

O3D是google公司开发的一套用于web3D开发的javascript API,是为了创建基于网页的3D图形操作界面和3D游戏而开发。网上经常有人把它拿来和OpenGL作比较,实际...

阅读全文

js对cookie的几个操作函数(仅作备忘)

js对cookie的几个操作函数,网上找的(仅作备忘) function getCookieVal(offset) {     var endstr = document.cookie.indexOf(“;”, offset);  ...

阅读全文

3则回应给“CGI返回弹出下载文件对话框的HTML代码”

  1. gf说道:

    赞一个!!

    [回复]

发表评论