javascript - Ajax 将 json 发送到 Spring Boot 服务器并在新选项卡中打开生成的 pdf
问题描述
我有一个小型 Web 应用程序,它从表单收集数据,通过 Ajax 将其发送到 Spring Boot 服务器。服务器生成 pdf 文件并将其作为字节数组发送回。然后我希望在新选项卡中打开一个 PDF,但我在那里看到空 PDF,这是我的问题。这是 Ajax 方法:
function sendJson(json) {
$.ajax({
url: "/pdf/create",
type: "POST",
data: json,
contentType: "application/json",
success: function (data) {
alert('Success');
openFile(data)
},
error: function (e) {
console.log('Was trying to send data, but error occurred. ' + json);
alert('Error sending data to server');
}
});
}
然后我根据收到的数据创建一个 blob 并打开它。
function openFile(byte) {
var file = new Blob([byte], {type: "application/pdf"});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
这是我的弹簧启动控制器:
@PostMapping(value = "/pdf/create")
public ResponseEntity<?> preparePdf(@RequestBody String data) throws IOException {
System.out.println("Data input: " + data);
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> dataObject = mapper.readValue(data, Map.class);
try {
return pdfService.createPdfFromTemplate(dataObject);
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.badRequest().body(HttpStatus.BAD_REQUEST);
}
}
处理在这里:
public ResponseEntity<Resource> createPdfFromTemplate(Map<String, Object> dataObject) throws IOException {
// data saved to DB. PDF is generated and saved locally
String filename = "generated_file.pdf";
File pdf = new File(filename);
byte[] fileBytes = FileUtils.readFileToByteArray(pdf);
ResponseEntity.BodyBuilder res = ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM);
return res.body(new ByteArrayResource(fileBytes));
}
生成的 pdf 中的文本是西里尔文,但我认为问题不在于这里,也不是某种编码。我想我在这里遗漏了一些重要的东西。有时我看到不能通过 ajax 或 POST 方法完成的意见不是一个好方法,但发送 json 数据并接收生成的文件似乎是合乎逻辑的。任何想法都表示赞赏。
解决方案
希望它对某人有用。我将我的字节数组编码为服务器端的 base64 字符串,Base64.getEncoder().encodeToString(fileBytes)
用作我的响应的主体。在 JS 打开文件之前,我将其转换为 ArrayBuffer,如下所示:
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
并且文件按我的预期在新选项卡中打开。
推荐阅读
- css - 如何用圆角掩盖图像?
- cmd - 如何在 JavaScript 中的 HTA 文件中获取 CMD 输出
- python-3.x - 检查一个unix时间是否在python3中的另外两个unix时间戳之间
- arrays - 用于在数组中查找重复项的代码,Scala
- java - 无法在 Ubuntu 上启动 Eclipse 退出代码 = 13
- c# - 如何使用C#打乱句子中的单词并放入数组
- c++ - 编译器优化消除了错误共享的影响。如何?
- python - dis.dis(foo) 中字段的正式名称
- c# - CSharp 和 Golang 之间的 AES-CFB 实现不一致
- security - 创建一个从 Windows 系统到 Kali 机器的反向 shell - 其中一个是侦听器