【发布时间】:2021-07-03 13:25:27
【问题描述】:
我正在努力从 Spring boot 生成的用户界面 (Angular) 下载 pdf 文件。 我可以使用相同的 API 从浏览器下载 pdf 文件。
我们将不胜感激快速帮助。
SyntaxError: 在 XMLHttpRequest.onLoad 的 JSON.parse () 位置 0 处的 JSON 中出现意外的标记 % 消息:“位置 0 处 JSON 中的意外令牌 %” 堆栈:“语法错误:在 XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:19662:51) 处 JSON.parse ()↵ 位置 0↵ 处的 JSON 中的意外令牌%↵
API 代码
控制器代码-
@RequestMapping(value = "/downloadPDF/", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity<Resource> downloadServicePack(@RequestHeader("Authorization") String token,
HttpServletRequest request) throws WorkflowException, Exception {
String fileName = "TWEVL_ServiceDesignPack.pdf";
// String fileName ="ServiceDesignPdf.pdf";
Resource resource = fileStorageService.loadFileAsResource(fileName);
// Try to determine file's content type
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
// logger.info("Could not determine file type.");
}
// Fallback to the default content type if type could not be determined
if (contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
服务代码-
@Service
public class FileStorageService {
private final Path fileStorageLocation;
@Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) throws Exception {
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new Exception("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public Resource loadFileAsResource(String fileName) throws Exception {
try {
Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if(resource.exists()) {
return resource;
} else {
throw new Exception("File not found " + fileName);
}
} catch (Exception ex) {
throw new Exception("File not found " + fileName, ex);
}
}
}
Angular 代码-
JWT 拦截器传递令牌和其他标头-
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
const token = this.authenticationService.currentUserValue;
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token.token}`,
Accept: `application/pdf`,
responseType:'blob',
'Content-Type':`application/pdf`
}
});
return next.handle(request);
}
}
API 调用
downloadServicePackPDF() {
this.tcmtSrv
.downloadServicePack()
.subscribe(
(blob: Blob) => {
console.log('report is downloaded');
},
(error) => {
console.log(error);
}
);
}
服务代码-
downloadServicePack() {
//header is being passed from interceptor
return this.apiSrv.get(DOWNLOAD_SERVICE_PACK,'');
}
【问题讨论】:
-
@R.Richards 我已经在标头中传递了 Accept 和 responseType。它给出了同样的错误。刚刚使用请求标头参数更新了帖子
-
我发现使用文件保护程序包对此很有帮助。查看此帖子stackoverflow.com/questions/53246489/…
-
您
responseType的做法不正确。那不是标题。仔细查看我发布的链接。 -
谢谢@R.Richards,你是对的。我没有按照您建议的方式传递 responseType。我试图通过它,但它不起作用。后来我检查了拦截器是否覆盖了在服务级别给出的这些标头和其他参数。所以我禁用了拦截器并且它工作但我无法禁用/删除拦截器。关于如何停止拦截器在特定 API 上运行的任何想法?如何停止覆盖拦截器在服务层传递的标头?
标签: javascript angular spring-boot pdf