- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现 POST
到网络服务。我需要发送一个类型为变量的文件( .docx
、 .pdf
、 .txt
)以及 JSON 格式的字符串。
我已经设法使用类似于以下的代码成功发布文件:
procedure DoRequest;
var
Http: TIdHTTP;
Params: TIdMultipartFormDataStream;
RequestStream, ResponseStream: TStringStream;
JRequest, JResponse: TJSONObject;
url: string;
begin
url := 'some_custom_service'
JRequest := TJSONObject.Create;
JResponse := TJSONObject.Create;
try
JRequest.AddPair('Pair1', 'Value1');
JRequest.AddPair('Pair2', 'Value2');
JRequest.AddPair('Pair3', 'Value3');
Http := TIdHTTP.Create(nil);
ResponseStream := TStringStream.Create;
RequestStream := TStringStream.Create(UTF8Encode(JRequest.ToString));
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFile('File', ceFileName.Text, '').ContentTransfer := '';
Params.AddFormField('Json', 'application/json', '', RequestStream);
Http.Post(url, Params, ResponseStream);
JResponse := TJSONObject.ParseJSONValue(ResponseStream.DataString) as TJSONObject;
finally
RequestStream.Free;
ResponseStream.Free;
Params.Free;
Http.Free;
end;
finally
JRequest.Free;
JResponse.Free;
end;
end;
POST
header 由 Indy 的
TIdFormDataField
编码使用
EncodeHeader()
的类功能。当 post 失败时,header 中的编码文件名会被拆分,而成功的 post 则不会被拆分。
Επιστολή εκπαιδευτικο.docx
被编码为 =?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66zr8uZG9j?='#$D#$A' =?UTF-8?B?eA==?=
,失败了。 Επιστολή εκπαιδευτικ.docx
被编码为=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66LmRvY3g=?=
, 成功了。 Επιστολή εκπαιδευτικ .docx
被编码为=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66?= .docx
,失败了。 AContentType
的
AddFile()
程序和
ContentTransfer
,但是这些都不会改变行为,并且在拆分编码的文件名时仍然会出错。
最佳答案
EncodeHeader()
Unicode 字符串确实存在一些已知问题:
EncodeHeader() needs to take codeunits into account when splitting data between adjacent encoded-words
基本上,一个 MIME 编码的单词长度不能超过 75 个字符,因此长文本会被拆分。但是在对长 Unicode 字符串进行编码时,任何给定的 Unicode 字符都可以使用 1 个或更多字节进行字符集编码,并且 EncodeHeader()
尚未避免错误地将两个单独字节之间的多字节字符拆分为单独的编码字(这是非法的,并且被 MIME 规范的 RFC 2047 明确禁止)。
但是,这不是您的示例中发生的情况。
在您的第一个示例中,'Επιστολή εκπαιδευτικο.docx'
太长而无法编码为单个 MIME 字,因此它被拆分为 'Επιστολή εκπαιδευτικο.doc'
'x'
子串,然后分别编码。 这在 MIME 中对于长文本是合法的 (尽管您可能希望 Indy 将文本拆分为 'Επιστολή'
' εκπαιδευτικο.doc'
,甚至 'Επιστολή'
' εκπαιδευτικο'
'.doc'
。这可能会在 future 的版本中出现)。仅由空格分隔的相邻 MIME 词意味着在解码时连接在一起而不分隔空格,从而产生 'Επιστολή εκπαιδευτικο.docx'
再次。如果服务器不这样做,则它的解码器存在缺陷(也许它正在解码为 'Επιστολή εκπαιδευτικο.doc x'
?)。
在您的第二个示例中,'Επιστολή εκπαιδευτικ.docx'
足够短,可以编码为单个 MIME 字。
在您的第三个示例中,'Επιστολή εκπαιδευτικ .docx'
在第二个空格(不是第一个)上被拆分为 'Επιστολή εκπαιδευτικ'
' .docx'
子字符串,并且只需要对第一个子字符串进行编码。 这在 MIME 中是合法的 .解码时,解码后的文本将与以下未编码的文本连接,在它们之间保留空格,从而产生 'Επιστολή εκπαιδευτικ .docx'
再次。如果服务器不这样做,则它的解码器存在缺陷(也许它正在解码为 'Επιστολή εκπαιδευτικ.docx'
?)。
如果您通过 Indy 的 MIME header 编码器/解码器运行这些示例文件名,它们会正确解码:
var
s: String;
begin
s := EncodeHeader('Επιστολή εκπαιδευτικο.docx', '', 'B', 'UTF-8');
ShowMessage(s); // '=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66zr8uZG9j?='#13#10' =?UTF-8?B?eA==?='
s := DecodeHeader(s);
ShowMessage(s); // 'Επιστολή εκπαιδευτικο.docx'
s := EncodeHeader('Επιστολή εκπαιδευτικ.docx', '', 'B', 'UTF-8');
ShowMessage(s); // '=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66LmRvY3g=?='
s := DecodeHeader(s);
ShowMessage(s); // 'Επιστολή εκπαιδευτικ.docx'
s := EncodeHeader('Επιστολή εκπαιδευτικ .docx', '', 'B', 'UTF-8');
ShowMessage(s); // '=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66?= .docx'
s := DecodeHeader(s);
ShowMessage(s); // 'Επιστολή εκπαιδευτικ .docx'
end;
所以问题似乎出在服务器端解码上,而不是在 Indy 的客户端编码上。
TIdFormDataField
有一个
HeaderEncoding
属性,默认为
'B'
(base64) 在 Unicode 环境中。但是,拆分逻辑也会影响
'Q'
(quoted-printable) 也是如此,所以这可能对你有用,也可能对你不起作用(但你可以试试):
with Params.AddFile('File', ceFileName.Text, '') do
begin
ContentTransfer := '';
HeaderEncoding := 'Q'; // <--- here
HeaderCharSet := 'utf-8';
end;
否则,解决方法可能是将值更改为
'8'
(8 位),它有效地禁用 MIME 编码(但不是字符集编码):
with Params.AddFile('File', ceFileName.Text, '') do
begin
ContentTransfer := '';
HeaderEncoding := '8'; // <--- here
HeaderCharSet := 'utf-8';
end;
请注意,如果服务器不希望文件名使用原始 UTF-8 字节,您可能仍然会遇到问题(例如,
'Επιστολή εκπαιδευτικο.docx'
被解释为
'Επιστολή εκπαιδευτικο.docx'
)。
关于delphi - 使用 Indy 发布且文件名包含希腊字符时,文件上传失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42390870/
任何帮助深表感谢。我正在尝试创建一个 SSIS 包来遍历文件夹中的文件并获取路径+文件名,最后执行存储的过程,参数为路径+文件名。我不确定如何获取路径+文件名并将其作为参数插入到存储过程中。我附上了截
我想编写一个小脚本来搜索确切的文件名,而不是文件名中的字符串。 例如,如果我使用资源管理器搜索“主机”,默认情况下我会得到多个结果。对于脚本,我只需要我指定的名称。我假设这可能吗? 我才真正开始编写脚
str(文件.key) = '1011/101011/文件名' newFileName = str(file.key) 但是,当我运行代码时,我得到: UnicodeEncodeError: 'asc
下面这段子程基本上可以算是比较不错的通用匹配了。(PS:我突然发现CODE_LITE把我的UBB转义了!!!晕,我只好自己转义了。。。) Dim objRegExp,Matc
PHP 无法处理带有 Unicode 字符的文件:当我在浏览器上访问 testSite/главная.php 时,它会抛出此错误。 Warning: Unknown: failed to open
我正在尝试包含 Dim在 Vlookup 中。 Dim filename As String filename = Format(DateAdd("d", -6, Now()), "mm-dd-yy"
在我的日常构建项目中,我们将其库存储到其版本名称目录中。 . 对于最新的,我们正在创建符号链接(symbolic link)作为“最新”。 前任。- ls -ltr drw-r--r-- 1 4096
重新安装了 Windows 10(版本 10.0.14393)。重新安装了以下内容: java java version "1.8.0_121" Java(TM) SE Runtime Environ
我想使用 Jekyll 和 GitHub Pages 构建文档站点。问题是 Jekyll 只接受 _posts 下的文件名具有精确的图案,如 YYYY-MM-DD-your-title-is-here
我不知道我发生了什么事。我想访问一个包含多个文件的目录,假设: folder\\1.txt 2.txt 3.txt.... 现在我想根据它们的出现情况来阅读它们,我的意思是首先是最低的,只是我想按升
如何将/放入文件名(即/不分隔路径的组成部分)? 最佳答案 你不知道。 UNIX 文件名中不允许使用斜线。 关于unix - 你如何获得 a/into 文件名?,我们在Stack Overflow上找
我需要复制一个大文件夹,并重命名其中的所有文件和文件夹(如果它们包含特定字符串)。基本上我想复制所有内容并将 10 的任何实例更改为 11。 例如,如果我有一个结构如下的文件夹: mainfolder
我有一个简单的 python (2.7) 脚本,应该执行一些 svn 命令: def getStatusOutput(cmd): print cmd p = subprocess.Po
我正在尝试读取以字符串形式存储在数据文件中的文件名。那里没问题。如果我将它传递给 genfromtxt,我会收到错误“IOError:Z:\Python\Rb input.txt not found”
简单的问题。 当我尝试打开名为 text.txt 的文件时,它可以正常工作。 但是,如果我将文件重命名为 text.cir.txt,则会出现错误。 我可以做什么来修复它? FILE *fd; char
我是 c# 的业余爱好者,我一直无法找到这个问题的答案。也许我不知道要使用的正确术语。 当一个视频文件被拖到我的 exe 应用程序上时,我希望应用程序知道它是用一个文件启动的,并且能够知道该文件的路径
我知道我必须使用 Substring 来删除,但我不知道该怎么做。我需要像这样删除字符串的结尾 来自 "C:\\Users\\myname\\Pictures\\shoeImage.jpg" 到 "C
运行 eclipse 时我收到此错误。但是当我运行我的项目时,它是在内部浏览器中执行的。但它不会在默认的系统浏览器中执行。对此任何一个答案。先谢谢您的回答 最佳答案 您可以从 eclipse 更改浏览
我想要求用户选择一个要从外部存储打开的文件并接收它的路径。最好我想避免过多的编码并使用一些标准方法(众所周知,系统提供的 Intent 或类似方法)。所说的文件是SpatiaLite db文件(*.s
我有一个文件名数据库,我正在尝试使用 PG 的全文搜索工具在其中进行搜索。我在文件名表上运行搜索查询,问题是排名函数没有按照我希望的那样对结果进行排名。为了便于讨论,我们假设架构如下所示: creat
我是一名优秀的程序员,十分优秀!