当前位置: 首页 > news >正文

解决node.js的req.body为空的问题

从昨晚一直在试,明明之前用的封装的axios发送请求给其他的后端(springboot)是可以的,但昨天用了新项目的后端(node.js)就不行。

之前用了代理,所以浏览器发送的post请求不会被拦截,但是昨天因为项目的接口没有统一前缀的原因(比如都用admin)开头,所以直接把baseUrl写成http://127.0.0.1:7123了,但是发送post请求出错,我还以为前端写错了,后面发现post请求的话总不行,报是跨域的问题,但是get的话就可以,查了一下,get的话请求参数会被放在query里面,post请求会跨域,所以node那边得写成  res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");原来的话是 res.header("Access-Control-Allow-Headers", "X-Requested-With")

解决跨域问题的写法:(记得加Content-Type)

res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");

总结,如果post用application/x-www-form-urlencoded,得格式化数据

   // 2. 使用 URLSearchParams 格式化数据const formData = new URLSearchParams();for (const key in data1) {formData.append(key, data1[key]);}// 3. 发送 POST 请求axios.post('http://127.0.0.1:7123/admin/login', formData, {headers: {'Content-Type': 'application/x-www-form-urlencoded',},})

如果post用json,则不用,因为axios会自动帮我们json化

    const data1 = {account: 'value1',password: 'value2'};// 2. 使用 URLSearchParams 格式化数据const formData = new URLSearchParams();for (const key in data1) {formData.append(key, data1[key]);}// 3. 发送 POST 请求axios.post('http://127.0.0.1:7123/admin/login', data1, {headers: {'Content-Type': 'application/json',},})

上面的例子是不封装的情况,如果是封装的话,如果传进来dataType:"json"格式,按照以下代码可以执行,因为这时候Content-Type为application/json,后端用req.body可以获取到

import axios from "axios"
import { ElLoading } from 'element-plus'; // 正确的拼写是 ElLoading,不是 Lloading
import router from '@/router'
import Message from '../utils/Message'
import { getCurrentInstance } from "vue";
const contentTypeForm='application/x-www-form-urlencoded;charset-UTF-8'
const contentTypeJson='application/json'
const contentTypeMulti ='multipart/form-data'
let loading=null;
import VueCookies from 'vue-cookies';
const instance=axios.create({baseURL:'http://127.0.0.1:7123', //请求后端接口的baseUrltimeout:10*1000, //设置请求的超时时间
})
//请求前拦截器
instance.interceptors.request.use((config)=>{const data= VueCookies.get("loginInfo");if(data){const token=data.token;if (token) {config.headers.token = token}}if(config.showLoading){loading=ElLoading.service({lock:true,text:'加载中……',background:'rgba(0,0,0,0.7)',})}return config;},(error)=>{if(config.showLoading&&loading){loading.close();}Message.error("请求发送失败");return Promise.reject("请求发送失败");}
);
//请求后拦截器
instance.interceptors.response.use((response)=>{const{showLoading,errorCallback,showError=true}=response.config;if(showLoading&&loading){loading.close();}//正常请求if (response.status==200){return response.data;}},(error)=>{const { showLoading, errorCallback, showError = true } = error.config;if (showLoading && loading) {loading.close();}(error.response);if(error.response){const responseData = error.response;if (responseData.status == 401) {setTimeout(() => {router.push("/login")}, 2000);return Promise.reject({ showError: true, msg: "登录超时" });}}if(error.config.showLoading&&loading){loading.close();}return Promise.reject({showError:true,msg:"网络异常"})}
);
const request = ({ url, method, params, dataType, showLoading = true, errorCallback, showError = true, data }) => {// 设置默认 Content-Typeconst contentType = method === 'upload' ? contentTypeMulti : (dataType === 'json' ? contentTypeJson : contentTypeForm);// 处理请求数据const requestData = method === 'upload' ? { data } : (method === 'get' || method === 'delete' ? { params } : { data: params });// 上传请求强制使用 POST 方法if (method === 'upload') {method = 'post';}return instance.request({method,url,...requestData,headers: {'Content-Type': contentType,'X-Requested-With': 'XMLHttpRequest',},showLoading,}).catch(error => {console.error(error);if (showError) {Message.error(error.msg || 'An error occurred');}if (errorCallback) {errorCallback(error);}return null;});
};export default request;

但是如果不传入dataType的话,默认为application/x-www-form-urlencoded的话,就要注意了,

 const requestData = method === 'upload' ? { data } : (method === 'get' || method === 'delete' ? { params } : { data: params });这行代码得改为 const requestData = method === 'upload' ? { data } : (method === 'get' || method === 'delete' ? { params } : { params });因为application/x-www-form-urlencoded是以 类似‘name=edward&age=25’  这样的形式放在参数中,后端得用req.query才能获取数据,req.body获取不到。

但是如果要在req.body获取得到的话,那么

import qs from 'qs';const request = axios.create({baseURL: process.env.BASE_URL,headers: {'Content-Type': 'application/x-www-form-urlencoded',}
})request.interceptors.request.use(config => {if (config.method === 'post') {config.data = qs.stringify(config.data)}return config;
})

记得要qs序列化。!!!!!!!!!!!!!!!!!!!!!!!!!

暂时先写这么多,后续有更清晰的理解再补充,哪里写错还请路过的大佬斧正。

贴一下原贴

post请求头设置成application/json时的跨域错误_指定contenttype为json后报跨域-CSDN博客

http://www.lryc.cn/news/504315.html

相关文章:

  • Mysql学习笔记之安装
  • 将PDF流使用 canvas 绘制然后转为图片展示在页面上(二)
  • 【深度学习】 零基础介绍卷积神经网络(CNN)
  • Coze概述
  • 康佳Android面试题及参考答案(多张原理图)
  • 2022 年 3 月青少年软编等考 C 语言四级真题解析
  • 关于24年408真题的疑问
  • 【容器】k8s学习笔记基础部分(三万字超详细)
  • dayjs(2kb)和momentjs(70kb)关系详述及项目中如何选择讲解
  • 【Python网络爬虫笔记】11- Xpath精准定位元素
  • 6.python列表
  • Android中bindService和startService启动服务有何区别
  • 超牛免费 机械臂模型、工业机器人模型下载网站集合
  • 引领未来的变革:15种前沿RAG技术及其应用探索
  • Scala泛型应用场景
  • AI监控赋能健身馆与游泳馆全方位守护,提升安全效率
  • Avalonia实战实例二:添加三种状态的Svg图片按钮
  • 基于注意力的几何感知的深度学习对接模型 GAABind - 评测
  • arcGIS使用笔记(无人机tif合并、导出、去除黑边、重采样)
  • Color-Light-Control-and-Four-Way-Responder based on STM32F103C8T6
  • openGauss开源数据库实战二十八
  • Vue3之响应式系统详解
  • Kafka 的配置文件
  • 【系统思辨】分散注意
  • 单幅图像合成 360° 3D 场景的新方法:PanoDreamer,可同时生成全景图像和相应的深度信息。
  • Python课设-谁为影狂-豆瓣数据【数据获取与预处理课设】
  • 关卡选择与布局器
  • 评估一套呼叫中心大模型呼出机器人的投入回报比?
  • 面向对象的 CLI:使用 Fire 简化类和对象的方法暴露 (中英双语)
  • flutter控件buildDragTargetWidget详解