使用axios.post提交FormData时遭遇Unsupported Media Type错误
问题:Axios POST请求Spring Boot返回415 Unsupported Media Type错误
我尝试通过axios.post向Spring Boot服务器发送包含文件和JSON数据的POST请求,代码片段如下:
export function createSingleProduct(productData) { const formData = new FormData(); const data = { categoryName: productData[0].product.categoryName, productName: productData[0].product.productName, serialNumber: productData[0].product.serialNumber, purchasePrice: parseInt(productData[0].product.purchasePrice), purchaseDate: productData[0].product.purchaseDate, warrantyInYears: parseInt(productData[0].product.warrantyInYears), warrantyExpiryDate: productData[0].product.warrantyExpiryDate, }; formData.append("product", data); formData.append("productPhoto", productData[0].productPhoto); const config = { headers: { apiKey: api_key, "Content-Type": "multipart/form-data", }, }; console.log(config.headers); return axios.post(`${API_BASE_URL}/products`, formData, config); }
尽管已经在请求头中指定了Content-Type: multipart/form-data,但仍收到如下错误:
{ "timestamp": "05-20-2023 01:27:36", "status": 415, "error": "Unsupported Media Type", "message": "Content type 'application/octet-stream' not supported", "path": "/product-crud/products" }
后端接口通过Postman测试完全正常,Postman生成的示例请求代码如下:
var axios = require('axios'); var FormData = require('form-data'); var fs = require('fs'); var data = new FormData(); data.append('product', '{\n "categoryName": "Electronics",\n "productName": "Desktop",\n "serialNumber": "5007",\n "purchasePrice": 45000.00,\n "purchaseDate": "2023-05-16",\n "warrantyInYears": 2,\n "warrantyExpireDate": "2025-05-16"\n}', {contentType: 'application/json'}); data.append('productPhoto', fs.createReadStream('/C:/Users/NSL/Pictures/desk-pc-header.png')); var config = { method: 'post', maxBodyLength: Infinity, url: `${Base_URL}/product-crud/products`, headers: { 'apiKey': api_key, ...data.getHeaders() }, data : data }; axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); }) .catch(function (error) { console.log(error); });
解决方案
问题根源在于直接将JSON对象传入FormData的append方法时,浏览器会默认将其转为字符串并标记为application/octet-stream类型,导致后端无法识别。需要用Blob包装JSON字符串并明确指定type: "application/json",修正后的代码如下:
export function createSingleProduct(productData) { let formData = new FormData(); const data = { categoryName: productData[0].product.categoryName, productName: productData[0].product.productName, serialNumber: productData[0].product.serialNumber, purchasePrice: parseFloat(productData[0].product.purchasePrice), purchaseDate: productData[0].product.purchaseDate, warrantyInYears: parseInt(productData[0].product.warrantyInYears), warrantyExpireDate: productData[0].product.warrantyExpiryDate, }; formData.append( "product", new Blob([JSON.stringify(data)], { type: "application/json", }) ); formData.append("productPhoto", productData[0].productPhoto); const config = { headers: { "Content-Type": "multipart/form-data", apiKey: api_key, }, }; return axios.post(`${API_BASE_URL}/products`, formData, config); }
内容的提问来源于stack exchange,提问作者Mushfikunnabi Nijhum
相关产品推荐
相关产品推荐

