reactjs - 通过 react/axios 从 spring 获取请求中查看 pdf
问题描述
我有一个 spring 端点,它提供一个 pdf 作为字节 [] 和一个当我尝试调用端点时得到 406 的 React ui。
弹簧端点:
@GetMapping(value = "report/{report_id}", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> generateReviewTaskReport(
HttpServletResponse response,
@PathVariable("report_id") String reportId,
@RequestAttribute(USER_ID) String loginId) {
byte[] report = reportService.generateReport(reportId, loginId);
ByteArrayInputStream inputStream = new ByteArrayInputStream(report);
HttpHeaders headers = new HttpHeaders();
headers.setContentLength(report.length);
headers.add("Content-Disposition", "inline;filename=" + reportId + "_report.pdf");
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(inputStream));
}
我试过了:
headers.add("Content-Disposition", "attachment;filename=" + reportId + "_report.pdf");
同样的结果。
反应请求:
export const getReport = (reportId = '') => (dispatch) => {
const report = `${apiConfig.reportUrl}${reportId}`
const promise = axios.get(report,
{
responseType: 'blob',
headers: {
'Accept': 'application/pdf'
}
})
return dispatch({
type: GET_REPORT,
payload: promise,
})
}
case GET_REPORT:
if (payload.data) {
const report = new Blob([payload.data])
reportUrl = URL.createObjectURL(report)
window.open(reportUrl, "_blank")
}
我试过 responseType:'bufferArray',从我的 spring 端点返回一个普通的 byte[],总是得到一个 406。我猜这是因为我的'Accept'标头中有错误的 mime 类型。我试过'application/pdf'和'*/*',结果一样。我需要哪些标头来接受 InputStreamResource 或 byte[]?
使用邮递员,我可以很好地下载文件。
我的配置:
@Component
public class WebConfiguration extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(byteArrayHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
}
@Bean
public HttpMessageConverter byteArrayHttpMessageConverter() {
ByteArrayHttpMessageConverter arrayHttpMessageConverter =
new ByteArrayHttpMessageConverter();
arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
return arrayHttpMessageConverter;
}
private List<MediaType> getSupportedMediaTypes() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_PDF);
mediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
return mediaTypes;
}
}
解决方案
一个通用的解决方案,但我认为在你的情况下它应该可以正常工作;)
axios({
url: 'http://api.dev/file-download', //your url
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
});
要点:https ://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
推荐阅读
- django - 将参数传递给 django 表单
- javascript - 如何按特定顺序对数组中的三个项目进行排序?
- node.js - INVALID_CREDENTIAL,“证书对象必须是一个对象。”)在 firebase-admin 节点应用程序中
- julia - 如何在 Julia 中测试数组中的所有元素是否具有相同的值
- java - 为什么 org.hibernate.hql.internal.ast.QuerySyntaxException:意外令牌:(近线?
- sharepoint - 针对暂停的爬网问题的计划增量爬网行为
- json - Ajax - JSON - 初学者
- flutter - 在颤振中使用流生成器时出现错误
- typescript - 打字稿:需要帮助强制对函数响应进行严格输入
- r - 如何在ggplot中为数字x轴的条形图添加直接标签