赞
踩
假设需要在UE中发送下方接口传输文件
使用From-data格式
在请求头Content-Type中加入间隔符Boundary
使用LoadFileToArray()读取文件,并加入分隔符、文件头等内容 转成字节 作为Content
创建BlueprintFunctionLibrary蓝图函数库
对应Build.cs中加入Http模块
PrivateDependencyModuleNames.Add("Http");
增加函数
.h中
UFUNCTION(BlueprintCallable, Category = "Gdoog", meta = (WorldContext = "WorldContextObject"))
//发送上传文件的请求
static void UploadFileHttp();
UFUNCTION(BlueprintPure, Category = "Gdoog", meta = (WorldContext = "WorldContextObject"))
//字符串转字节,支持中文
static TArray<uint8> ConvertStringToBytes(const FString& Data);
.cpp中
函数前改为自己的函数库名
文件读取相关头文件
#include “HAL/PlatformFileManager.h”
#include “Misc/FileHelper.h”
http相关头文件
#include “HttpModule.h”
//字符串转字节,支持中文 TArray<uint8> UG_FileHelperForBpBPLibrary::ConvertStringToBytes(const FString& Data) { TArray<uint8> ResBytes; FTCHARToUTF8 Converter(*Data); ResBytes.SetNum(Converter.Length()); FMemory::Memcpy(ResBytes.GetData(), (uint8*)(ANSICHAR*)Converter.Get(), ResBytes.Num()); return ResBytes; } //发送上传文件的请求 void UG_FileHelperForBpBPLibrary::UploadFileHttp() { const FString FilePath = "E:\\XiTong\\Desktop\\测试文件.xls";//文件路径 const FString FileName = FPaths::GetCleanFilename(FilePath);//文件名字 const FString HttpUrl = "127.0.0.1:1024/upload";//请求链接 const FString HttpVerb = "POST";//请求方式 const FString KeyOfFile = "file";//请求中文件的key const FString TypeOfFile = "application/vnd.ms-excel";//文件类型对应的type TMap<FString,FString> OtherInfo={{"Key1","Value1"},{"Key2","Value2"}};//其他请求参数 TArray<uint8> FileContentBytes;//文件内容 FFileHelper::LoadFileToArray(FileContentBytes, *FilePath); //随便创建一个间隔符 const FString BoundaryLabel = FString(TEXT("e543322540af456f9a3773049ca02529-")) + FString::FromInt(FMath::Rand()); //每个参数的头部都需要增加的 间隔符 const FString BoundaryBegin = FString(TEXT("--")) + BoundaryLabel + FString(TEXT("\r\n")); //结束时需要增加的 间隔符 const FString BoundaryEnd = FString(TEXT("\r\n--")) + BoundaryLabel + FString(TEXT("--\r\n")); //处理请求内容 TArray<uint8> ResContent; /* 文件内容前 例 \r\n * --e543322540af456f9a3773049ca02529-183\r\n * Content-Disposition: form-data; name="file"; filename="测试文件.xls"\r\n * Content-Type: application/vnd.ms-excel\r\n\r\n */ const FString BeginFileString = "\r\n" + BoundaryBegin + "Content-Disposition: form-data; name=\"" + KeyOfFile + "\"; filename=\"" + FileName + "\"\r\n" + "Content-Type: " + TypeOfFile + "\r\n\r\n"; //加入文件前内容 ResContent.Append(ConvertStringToBytes(BeginFileString)); //加入文件内容 ResContent.Append(FileContentBytes); /* 加入其他参数 例 \r\n * --e543322540af456f9a3773049ca02529-183\r\n * Content-Disposition: form-data; name="Key1"\r\n\r\n * Value1 */ for (TPair<FString, FString> Info : OtherInfo) { ResContent.Append(ConvertStringToBytes( "\r\n" + BoundaryBegin + "Content-Disposition: form-data; name=\""+ Info.Key+"\"\r\n\r\n" + Info.Value)); } //加入结尾分隔符 ResContent.Append(ConvertStringToBytes(BoundaryEnd)); //创建请求 FHttpModule& HttpModule = FHttpModule::Get(); TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = HttpModule.CreateRequest(); HttpRequest->SetURL(HttpUrl); HttpRequest->SetVerb(HttpVerb); //替换请求头中的type,加入间隔符 HttpRequest->SetHeader(TEXT("Content-Type"), FString(TEXT("multipart/form-data; boundary=")) + BoundaryLabel); //请求内容 HttpRequest->SetContent(ResContent); //请求回调,按需处理 // HttpRequest->OnProcessRequestComplete().BindLambda([this](UE_LOG(LogTemp, Error, TEXT("Connection."));); //发送 HttpRequest->ProcessRequest(); }
其中
const FString TypeOfFile = “application/vnd.ms-excel”;//文件类型对应的type
可以对照这个表去设置
常见 content-type对应表https://blog.csdn.net/xiaoyu19910321/article/details/79279364
函数的变量可以 按需 暴露给蓝图
如果有使用插件的节点来请求http,比如这里使用的HttpLibrary插件,只需要构建Content,然后在请求头中的Content_Type加入分隔符即可
构建过程与上文相同,多了一步返回分隔符的步骤
UFUNCTION(BlueprintCallable, Category = "Gdoog|File|Http", meta = (DisplayName = "LoadFileToParameter", AutoCreateRefTerm="OtherInfo"))
//将文件转化为入参,返回分隔符
static bool LoadFileToParameter_G(const FString FileKey, const FString FilePath, const FString FileType, const TMap<FString, FString>& OtherInfo,TArray<uint8>& Result,FString& Boundary);
//将文件转化为入参 bool UG_FileHelperForBpBPLibrary::LoadFileToParameter_G(const FString FileKey, const FString FilePath, const FString FileType, const TMap<FString, FString>& OtherInfo,TArray<uint8>& Result,FString& Boundary) { //Preprocess some values Return Boundary Boundary = FString(TEXT("e543322540af456f9a3773049ca02529-")) + FString::FromInt(FMath::Rand()); const FString BoundaryBegin = FString(TEXT("--")) + Boundary + FString(TEXT("\r\n")); const FString BoundaryEnd = FString(TEXT("\r\n--")) + Boundary + FString(TEXT("--\r\n")); TArray<uint8> FileBytes; FFileHelper::LoadFileToArray(FileBytes, *FilePath); //Build content Result.Append(ConvertStringToBytes( "\r\n" + BoundaryBegin + "Content-Disposition: form-data; name=\"" + FileKey + "\"; filename=\"" + FilePath + "\"\r\n" + "Content-Type: " + FileType + "\r\n\r\n")); Result.Append(FileBytes); for (TPair<FString, FString> Info : OtherInfo) { Result.Append(ConvertStringToBytes( "\r\n" + BoundaryBegin + "Content-Disposition: form-data; name=\"" + Info.Key + "\"\r\n\r\n" + Info.Value)); } Result.Append(ConvertStringToBytes_G(BoundaryEnd)); return true; }
最后效果
需要额外注意使用的插件能否替换请求头中的Content_Type
作者使用的插件 在选择FromData之后是无法替换Content-Type的
修改判断条件 使其允许修改
Upload an image using HTTP POST request C++
UE4如何上传文件
ue4/ue5 Http上传文件
常见 content-type对应表
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。