欢迎大家进群,一起探讨学习

微信公众号,每天给大家提供技术干货

博主技术笔记

博主网站地址1

博主网站地址2

博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star

vue的axios在ie和苹果浏览器后端参数数据接收不到的问题

ie和苹果手机的浏览器通过axios请求后端接口,后端获取不到的原因是,ie和苹果的浏览器支持Content-type是 application/x-www-form-urlencoded 所以你需要在请求修改Content-type为application/x-www-form-urlencoded

request.js

import axios from 'axios'
import Cookies from "js-cookie";
import {Message,
} from 'element-ui'
import store from '../store'
import {getToken,getAes,
} from '@/utils/auth'
import {AESDecrypt
} from '@/api/aes'
// 创建axios实例
const service = axios.create({baseURL: process.env.BASE_API, // api的base_urltimeout: 600000 // 请求超时时间
})// request拦截器
service.interceptors.request.use(config => {//获取登录成功后store中的tokenif (store.getters.token) {//如果有toekn才携带请求头中的token到后端config.headers['x-access-token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改}//由于在没有登录之前需要对后端提示做国际化,所以就去掉了token的验证,让每个请求携带语言标识config.headers['x-access-language'] = Cookies.get('locale')//官网只查询上线的数据config.headers['x-line'] = "0"//兼容ie和苹果手机的浏览器,默认是不支持appliction/json方式config.headers['Content-type'] = "application/x-www-form-urlencoded"return config
}, error => {// Do something with request errorconsole.log(error) // for debugPromise.reject(error)
})// respone拦截器
service.interceptors.response.use(response => {/*** code为非200是抛错 可结合自己业务进行修改*/var res;//判断服务器返回是否是加密数据if (response.data.responseData != null && response.data.responseData != "") {//进行解密数据let aesDecrypt = AESDecrypt(response.data.responseData, getAes());//解密后转换成jsonres = JSON.parse(aesDecrypt);} else {//不是加密的数据正常返回res = response.data}if (!res.success) {//登录失败我需要自己自定义错误,所以这里就不需要帮我弹框出来if (res.errorCode === "-302") {return Promise.reject('error');}//这里的意思除了就是状态码为E0707不需要它帮我打印出错误信息,我自己定义,其它都进行打印if (res.errorCode === "E0707" || res.errorCode === "E0706") {return res}//如果客户端密钥已经失效提示用户重新登录或者最新的密钥if (res.errorCode === "E0708" || res.errorCode === 'E0701') {alert(res.errorCode)store.dispatch('FedLogOut').then(() => {location.reload() // 为了重新实例化vue-router对象 避免bug})return;}Message({message: res.errorMsg,type: 'error',duration: 3 * 1000})return Promise.reject('error')} else {return res}},error => {//如果客户端密钥已经失效或者token失效提示用户重新登录if (error.response.status === 678) {store.dispatch('FedLogOut').then(() => {location.reload() // 为了重新实例化vue-router对象 避免bug})return Promise.reject(error);}if (error.response.status == 401) {location.href = "/login";return Promise.reject(error)}console.log('err' + error) // for debugMessage({message: error.message,type: 'error',duration: 3 * 1000})return Promise.reject(error)}
)export default service

后端修改,我用的框架是SpringCloud Alibaba,网关修改如下

package com.yoostar.gateway.filter;import com.alibaba.fastjson.JSONObject;
import com.yoostar.gateway.constants.Constant;
import com.yoostar.gateway.util.AESUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import javax.annotation.Resource;/*** 处理前端请求体解密和** @author bright* @date 2020-09-18*/
@Component
@Slf4j
public class RequestBodyFilter implements GlobalFilter, Ordered {@Resourceprivate RedisTemplate<String, String> redisTemplate;@SneakyThrows@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//获取aes密钥String keypair = redisTemplate.opsForValue().get(Constant.AES_KEY);log.info("redis-key [{}]", keypair);//获取ServerHttpRequest对象ServerHttpRequest request = exchange.getRequest();//根据请求头的x-aes 判断请求参数是否需要加密HttpHeaders head = request.getHeaders();String encryptionFlag = head.getFirst("x-aes");if (encryptionFlag != null) {if (encryptionFlag.equals(Constant.ENCRYPTION_FLAG)) {return chain.filter(exchange);}}//获取请求类型String methodValue = request.getMethodValue();//获取Content-typeString contentType = head.getFirst("Content-type");log.info("requestUrl [{}], Content-type [{}],  method [{}]", request.getURI(), contentType, methodValue);//获取请求体Object requestBody = exchange.getAttribute("cachedRequestBodyObject");String requestData = "";//PUT请求Content-type可以是application/json,application/json;charset=utf-8,application/x-www-form-urlencodedif (methodValue.equalsIgnoreCase(HttpMethod.PUT.toString())) {requestData = InterceptFormData(requestBody);} else {//如果是post请求的看 Content-type 为application/x-www-form-urlencoded还是application/json类型if (null != contentType) {//Content-type不同数据解密方式不同,需要做特殊处理// 兼容ie和苹果手机的浏览器,默认是不支持application/json方式if (contentType.equalsIgnoreCase(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {requestData = InterceptFormData(requestBody);} else {requestData = InterceptPost(requestBody, request);}}}log.info("\n 加密串》requestBody[{}]", requestData);if (!requestData.equals("")) {//获取解密后的内容String content = AESUtil.aesDecrypt(requestData, keypair);log.info("\n 解密后》requestBody[{}]", content);// mediaTypeMediaType mediaType = exchange.getRequest().getHeaders().getContentType();// read & modify bodyServerRequest serverRequest = new DefaultServerRequest(exchange);Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType) || MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)) {// 对原先的body进行修改操作return Mono.just(content);}return Mono.empty();});BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);HttpHeaders headers = new HttpHeaders();headers.putAll(exchange.getRequest().getHeaders());headers.remove(HttpHeaders.CONTENT_LENGTH);/*由于Content-type为application/x-www-form-urlencoded的时候 后端@requestBody获取不到参数所以这里需要修改CONTENT_TYPE为 application/json《删除 CONTENT_TYPE》*/headers.remove(HttpHeaders.CONTENT_TYPE);CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {@Overridepublic HttpHeaders getHeaders() {long contentLength = headers.getContentLength();HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.putAll(super.getHeaders());if (contentLength > 0) {httpHeaders.setContentLength(contentLength);} else {httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");}//重新设置CONTENT_TYPE为 application/jsonhttpHeaders.setContentType(MediaType.APPLICATION_JSON);return httpHeaders;}@Overridepublic Flux<DataBuffer> getBody() {return outputMessage.getBody();}};return chain.filter(exchange.mutate().request(decorator).build());}));}return chain.filter(exchange);}/*** 如果是post请求的只能是 Content-type 为application/x-www-form-urlencoded* 如果是PUT请求可以是application/json,application/json;charset=utf-8,application/x-www-form-urlencoded* 三种类型** @param requestData* @return*/public String InterceptFormData(Object requestData) {if (requestData != null && !requestData.equals("")) {String s = "{\"requestData\":";if (!requestData.toString().startsWith(s)) {throw new RuntimeException("参数【requestData】缺失异常!");} else {int closeLen = requestData.toString().length() - 1;int openLen = "{\"requestData\":".length();String substring = StringUtils.substring(requestData.toString(), openLen, closeLen);return substring;}}return "";}/*** 截取POST请求body的加密数据* 这是  Content-type 为 application/json或者* application/json;charset=utf-8类型 才可以** @param requestBody* @param request* @return*/public String InterceptPost(Object requestBody, ServerHttpRequest request) {//过滤一些请求,因为支付的回调里面的参数是没有加密的所以转换会出现问题,所以需要过滤下支付的回调地址if (request.getURI().toString().indexOf("/member/paypal/ipn/back") != -1|| request.getURI().toString().indexOf("/member/dlocal/back") != -1|| request.getURI().toString().indexOf("/member/dlocal/cancel") != -1) {return "";}//将请求体json对象转换为JSONObjectJSONObject jsonObject = (JSONObject) JSONObject.toJSON(requestBody);//获取加密串String requestData = "";if (requestBody != null) {requestData = jsonObject.get("requestData").toString();}return requestData;}@Overridepublic int getOrder() {return -2;}
}

vue的axios在ie和苹果浏览器后端参数数据接收不到的问题相关推荐

  1. springboot+jwt+shiro+vue+elementUI+axios+redis+mysql完成一个前后端分离的博客项目(笔记,帮填坑)

    根据B站up主MarkerHub视频制作的一个笔记 我的博客 B站博主链接: https://www.bilibili.com/video/BV1PQ4y1P7hZ?p=1 博主的开发文档: http ...

  2. vue中axios利用blob实现文件浏览器下载

    背景 在vue中,使用axios向后台请求数据,但只接收返回的response并不能实现浏览器下载,所以需要借助于blob实现文件的浏览器下载,分为两种情况,一种是get请求,使用params,另一种 ...

  3. VUE之Vxe-table动态生成多级表头及后端返回数据的处理

    需求: 1.第一列为正常列: 2.第二列开始为动态生成列(根据接口返回数据生成): 3.最后一列为编辑列. 步骤: 写入动态html模板 <vxe-tableid="prdReques ...

  4. Vue通过Axios向后台发送Post请求,浏览器Console提示405,后台显示Get请求不支持--解决办法

    Vue通过Axios向后台发送Post请求,浏览器Console提示405,后台显示Get请求不支持–解决办法 问题场景: axios默认是发送get请求,我要给后台发送一组用户填写的表单数据,逻辑简 ...

  5. vue项目解决苹果浏览器的缓存功能

    在开发vue项目的时候,测试人员给我提了一个bug:"苹果自带浏览器登录后杀死浏览器重新进入后,页面刷新所有数据不显示". 我仔细的回顾了一下代码,感觉我的代码没有什么问题,问测试 ...

  6. vue中axios的封装以及使用

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.axios 在src下新建 network 文件夹 network文件夹: 网络模块 放网络请求 ind ...

  7. vue 使用axios

    axios 基于http客户端的promise,面向浏览器和nodejs 特点 从浏览器中创建 XMLHttpRequests 从 node.js 创建 http 请求 支持 Promise API ...

  8. vue中Axios网络请求之Vue知识点归纳(十)

    本文描述 vue 中 Axios 简述 vue 中使用 Axios 发起 get 请求 vue 中使用 Axios 发起 post 请求 1 简述 Axios是一个基于Promise(ES6中用于处理 ...

  9. axios 超时_聊聊 Vue 中 axios 的封装

    axios 是 Vue 官方推荐的一个 HTTP 库,用 axios 官方简介来介绍它,就是: Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 作为一 ...

最新文章

  1. Oracle date 和 timestamp 区别
  2. cactus java,使用cactus实现对servlet进行单元测试
  3. 计算机网络实验仿真系统设计,计算机网络实验课程仿真系统平台的研究与设计...
  4. C++题解-Leecode 375. 猜数字大小 II——Leecode每日一题系列
  5. 任意进制转化 函数 模板(一)
  6. (转)DirectShow9在VS2005或vc6.0下编译出现问题的解决方法
  7. 云和恩墨张皖川:产品能力提升是推动国产替代进程的关键因素
  8. pyqt5 qscrollarea到达_PyQt5如何用QPainter在QScrollArea上画线?
  9. 一个android应用开发的感悟
  10. [导入]XACT与X3DAudio整合的问题
  11. MIPS指令集确实够精简,编译文件明显小
  12. 如果有一天,程序员不想做程序了,首选要做什么呢?
  13. (转)等保二级三级差异纵向对比表
  14. IMAP协议与imbox第三方库读取所有邮件
  15. 小说全自动采集详细过程-支持各大开源小说CMS采集
  16. MSM8937系统启动流程【转】
  17. 产品营销策划方案:6个创意来源
  18. C++构造函数与类型转换explicit(大疆2018校招软件组考点之一)
  19. TELNET协议笔记
  20. Python 在线多人游戏开发教程 Day05#石头剪刀布游戏

热门文章

  1. php整型占几个字节,转:int类型究竟占几个字节
  2. Linux操作系统下测试磁盘读写速度
  3. 晶圆测试软件,半导体晶圆接触角测量仪 Wafer水滴测试
  4. 半导体晶圆翘曲度测试方法
  5. MATLAB——建立多项式形式的传递函数及多项式系数提取
  6. 注意力机制 - 注意力汇聚:Nadaraya-Watson核回归
  7. 自主招生计算机专业报名条件,2017自主招生报考,需要提前做哪些准备?
  8. 手把手教你在ubuntu上安装搜狗输入法
  9. 20221014 芯片封装介绍
  10. 包子笔记 - 德隆大师在高谈阔论赚大钱的要点