如何使用QNetworkRequest/QUrl向S3上传路径包含'+'字符的文件
解决方案
AWS S3对URL路径部分的+字符解析不符合RFC 3986规范,会将其误判为application/x-www-form-urlencoded格式中的空格,所以必须手动将路径中的+编码为%2B才能符合S3的解析逻辑。Qt的QUrl默认不会编码路径中的+,因为该字符在RFC 3986的路径规则中属于合法无需编码的字符,所以需要手动调整编码逻辑,可用以下两种方案解决:
- 方案1:单独编码S3对象路径,显式指定编码
+字符
用QUrl::toPercentEncoding方法手动指定额外需要编码的字符列表,把+加入编码范围,示例代码:QString s3ObjectKey = "my+file.jpg"; // 你的S3对象路径 // 第二个参数指定保留不编码的字符(这里保留路径分隔符/),第三个参数指定额外需要编码的字符 QByteArray encodedKey = QUrl::toPercentEncoding(s3ObjectKey, "/", "+"); QUrl s3RequestUrl("https://你的桶名.s3.区域.amazonaws.com"); // 用StrictMode传入已经编码好的路径,避免QUrl二次转义 s3RequestUrl.setPath(QString::fromLatin1(encodedKey), QUrl::StrictMode); QNetworkRequest request(s3RequestUrl); - 方案2:全局替换编码后URL中的
+
如果你已经完成了QUrl的构造,不想修改前面的路径拼接逻辑,可以直接对编码后的URL字节做替换,再重新生成QUrl:QUrl originalUrl = /* 你原来构造的S3请求URL */; QByteArray encodedUrl = originalUrl.toEncoded(); // 仅当你的请求URL的查询参数部分没有需要保留的+时可用此方法,否则需要拆分URL只替换路径部分 encodedUrl.replace('+', "%2B"); QUrl fixedUrl = QUrl::fromEncoded(encodedUrl); QNetworkRequest request(fixedUrl);
两种方案都可以保证最终发送的HTTP请求路径中+会被替换为%2B,适配S3的特殊解析规则。
内容的提问来源于stack exchange,提问作者richb
相关产品推荐
相关产品推荐

