解决webserver在IE下载文件,文件名为乱码问题

通常使用以下代码就能导出为流的文件,而不是打开文件

websWrite(wp, T("HTTP/1.1 200 OK\n"));
websWrite(wp, T("Pragma: no-cache\n"));
websWrite(wp, T("Cache-control: no-cache\n"));
websWrite(wp, T("Content-Length: %ld\n"),sbufs.st_size);
websWrite(wp, T("Content-Type: application/force-download\n"));
websWrite(wp, T("Content-Type: application/vnd.ms-excel; charset=utf-8\n"));
// websWrite(wp, T("Content-type: application/octet-stream\n"));
websWrite(wp, T("Content-Transfer-Encoding: binary\r\n"));
websWrite(wp, T("Content-Disposition: attachment; filename=\"%s\"\n\n"),pname);

webserver支持下载的函数:

/**
* @brief URLEncode 对字符串URL编码
*
* @param str 原字符串
* @param strSize 原字符串长度(不包括最后的\0)
* @param result 结果缓冲区的地址
* @param resultSize 结果缓冲区的大小(包括最后的\0)
*
* @return: >0:resultstring 里实际有效的长度
* 0: 解码失败.
*/
int URLEncode(const char* str, const int strSize, char* result, const int resultSize)
{
int i;
int j = 0;//for result index
char ch;

if ((str==NULL) || (result==NULL) || (strSize<=0) || (resultSize<=0)) {
return 0;
}

for ( i=0; (i<strSize)&&(j<resultSize); ++i) {
ch = str[i];
if (((ch>='A') && (ch<'Z')) ||
((ch>='a') && (ch<'z')) ||
((ch>='0') && (ch<'9'))) {
result[j++] = ch;
} else if (ch == ' ') {
result[j++] = '+';
} else if (ch == '.' || ch == '-' || ch == '_' || ch == '*') {
result[j++] = ch;
} else {
if (j+3 < resultSize) {
sprintf(result+j, "%%%02X", (unsigned char)ch);
j += 3;
} else {
return 0;
}
}
}

result[j] = '\0';
return j;
}
#define BUFFER_SIZE 2048
static void downloadFiles(webs_t wp, char_t *path, char_t *query)
{
char _filePath[1024]={0},encodFilename[1024]={0};
char *fileName,*file_path,*browser,*pname;
unsigned char data[BUFFER_SIZE]={0};
char err_msg[256];
long count;
struct stat sbufs;
FILE *src;

fileName = websGetVar(wp, T("downFileName"), T(""));
file_path = websGetVar(wp, T("download_path"), T(""));
browser = websGetVar(wp, T("browserType"), T("")); //浏览器类型
sprintf(_filePath,"/media%s",file_path);
memset(&sbufs,0,sizeof(sbufs));


src = fopen(_filePath, "r");
if (!src) {
websWrite(wp, T("HTTP/1.1 200 OK\nContent-type: text/plain\nPragma: no-cache\nCache-Control: no-cache\n\n"));
sprintf (err_msg, "Can't fopen %s: %s\n", _filePath, strerror(errno));
websWrite(wp,T("%s"),err_msg);
websDone(wp, 200);
goto error;
}
if(!strcmp(browser,"IE")){
URLEncode(fileName, strlen(fileName), encodFilename, sizeof(encodFilename));
pname=encodFilename;
}else{
pname=fileName;
}

stat(_filePath, &sbufs);
websWrite(wp, T("HTTP/1.1 200 OK\n"));
websWrite(wp, T("Pragma: no-cache\n"));
websWrite(wp, T("Cache-control: no-cache\n"));
websWrite(wp, T("Content-Length: %ld\n"),sbufs.st_size);
websWrite(wp, T("Content-Type: application/force-download\n"));
websWrite(wp, T("Content-Type: application/vnd.ms-excel; charset=utf-8\n"));
// websWrite(wp, T("Content-type: application/octet-stream\n"));
websWrite(wp, T("Content-Transfer-Encoding: binary\r\n"));
websWrite(wp, T("Content-Disposition: attachment; filename=\"%s\"\n\n"),pname);

while ((count = fread(data, 1, BUFFER_SIZE, src)) > 0) {
websWriteBlock(wp, data, count);
}
fclose(src);

error:
return;
//websDone(wp, 200);
}



但是,如果fileName是UTF-8编码的,比如文件名为测试.html;
ie这时就搞些小情绪,文件名变成了乱码了

在RFC2231的定义里面, 多语言编码的Content-Disposition应该这么定义:
Content-Disposition: attachment; filename*="utf8''%E6%B5%8B%E8%AF%95.html"
即:
filename后面的等号之前要加 *
filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和urlencode过的文件名。
所以这时应该对文件名进行url编码转换 ,使用urlencode很轻松就搞定了

因此,以上代码应该加上url编码转换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值