最近遇到一个前端,请求参数不是按照json来搞的,给我整迷了,而且她还比较倔强。因为后端框架是统一按照json的格式接收和返回数据的(例外的除外),接下来就下一个请求后端的方法,大家可以参考一下:

前端先写一个js,请求客户列表数据的方法:

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="客户名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入客户名称"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="客户编号" prop="accountNo">
        <el-input
          v-model="queryParams.accountNo"
          placeholder="请输入客户编号"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="证件类型" prop="identitytype">
        <el-select v-model="queryParams.identitytype" placeholder="请选择证件类型" clearable size="small">
          <el-option
            v-for="dict in dict.type.identitytype"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="证件号码" prop="identityno">
        <el-input
          v-model="queryParams.identityno"
          placeholder="请输入证件号码"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="客户状态" prop="state">
        <el-input
          v-model="queryParams.state"
          placeholder="请输入客户状态"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:account:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:account:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:account:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:account:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="accountList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="实体主键" align="center" prop="objid" />
      <el-table-column label="负责人" align="center" prop="ownerid" />
      <el-table-column label="客户名称" align="center" prop="name" />
      <el-table-column label="客户编号" align="center" prop="accountNo" />
      <el-table-column label="证件类型" align="center" prop="identitytype">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.identitytype" :value="scope.row.identitytype"/>
        </template>
      </el-table-column>
      <el-table-column label="证件号码" align="center" prop="identityno" />
      <el-table-column label="客户状态" align="center" prop="state" />
      <el-table-column label="财汇企业代码" align="center" prop="itcode" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:account:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:account:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改客户管理对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="客户名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入客户名称" />
        </el-form-item>
         <el-form-item label="客户编号" prop="account_no">
          <el-input v-model="form.account_no" placeholder="请输入客户编号" />
        </el-form-item>
        <el-form-item label="证件类型" prop="identitytype">
          <el-select v-model="form.identitytype" placeholder="请选择证件类型">
            <el-option
              v-for="dict in dict.type.identitytype"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="证件号码" prop="identityno">
          <el-input v-model="form.identityno" placeholder="请输入证件号码" />
        </el-form-item>
        <el-form-item label="客户状态" prop="state">
          <el-input v-model="form.state" placeholder="请输入客户状态" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listAccount, getAccount, delAccount, addAccount, updateAccount } from "@/api/system/account";

export default {
  name: "Account",
  dicts: ['identitytype'],
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 客户管理表格数据
      accountList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        createtimestamp: null,
        updatetimestamp: null,
        version: null,
        entityname: null,
        createdby: null,
        updateby: null,
        ownerid: null,
        name: null,
        accountNo: null,
        grade: null,
        category: null,
        categoryA: null,
        categoryB: null,
        identitytype: null,
        identityno: null,
        parentid: null,
        groupid: null,
        accountLevel: null,
        state: null,
        itcode: null,
        ftName: null,
        engName: null,
        manager: null,
        tAccountLevel0: null,
        area: null,
        area0: null,
        area1: null,
        area2: null,
        area3: null,
        area4: null
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        name: [
          { required: true, message: "客户名称不能为空", trigger: "blur" }
        ],
        identitytype: [
          { required: true, message: "证件类型不能为空", trigger: "blur" }
        ],
        identityno: [
          { required: true, message: "证件号码不能为空", trigger: "blur" }
        ],
        state: [
          { required: true, message: "客户状态不能为空", trigger: "blur" }
        ],
         account_no: [
          { required: true, message: "客户编号不能为空", trigger: "blur" }
        ],
      }
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询客户管理列表 */
    getList() {
      this.loading = true;
      listAccount(this.queryParams).then(response => {
        this.accountList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        objid: null,
        createtimestamp: null,
        updatetimestamp: null,
        version: null,
        entityname: null,
        createdby: null,
        updateby: null,
        ownerid: null,
        name: null,
        accountNo: null,
        grade: null,
        category: null,
        categoryA: null,
        categoryB: null,
        identitytype: null,
        identityno: null,
        parentid: null,
        groupid: null,
        accountLevel: null,
        state: null,
        itcode: null,
        ftName: null,
        engName: null,
        manager: null,
        tAccountLevel0: null,
        area: null,
        area0: null,
        area1: null,
        area2: null,
        area3: null,
        area4: null
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.objid)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加客户管理";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const objid = row.objid || this.ids
      getAccount(objid).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改客户管理";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.objid != null) {
            updateAccount(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addAccount(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const objids = row.objid || this.ids;
      this.$modal.confirm('是否确认删除客户管理编号为"' + objids + '"的数据项?').then(function() {
        return delAccount(objids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/account/export', {
        ...this.queryParams
      }, `account_${new Date().getTime()}.xlsx`)
    }
  }
};
</script>

我把请求客户查询的方法单独摘出来:

/** 查询客户管理列表 */
    getList() {
      this.loading = true;
      listAccount(this.queryParams).then(response => {
        this.accountList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },

会发现有一个东西“listAccount”需要引入:

import { listAccount, getAccount, delAccount, addAccount, updateAccount } from "@/api/system/account";

然后带大家去看这个路径里面的方法是啥:
往下看了一下代码,哦?原来是针对客户列表数据做“增删改查”操作的js。

import request from '@/utils/request'

// 查询客户管理列表
export function listAccount(query) {
  return request({
    url: '/system/account/list',
    method: 'get',
    params: query
  })
}

// 查询客户管理详细
export function getAccount(objid) {
  return request({
    url: '/system/account/' + objid,
    method: 'get'
  })
}

// 新增客户管理
export function addAccount(data) {
  return request({
    url: '/system/account',
    method: 'post',
    data: data
  })
}

// 修改客户管理
export function updateAccount(data) {
  return request({
    url: '/system/account',
    method: 'put',
    data: data
  })
}

// 删除客户管理
export function delAccount(objid) {
  return request({
    url: '/system/account/' + objid,
    method: 'delete'
  })
}

// 导出客户管理
export function exportAccount(query) {
  return request({
    url: '/system/account/export',
    method: 'get',
    params: query
  })
}

大家会发现每一个方法里面都有一个“request”:

// 查询客户管理列表
 export function listAccount(query) {
 return request({
 url: ‘/system/account/list’,
 method: ‘get’,
 params: query
 })
 }

没办法,继续看为啥要因引入这个方法了:

import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import { saveAs } from 'file-saver'

let downloadLoadingInstance;

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})

// request拦截器
service.interceptors.request.use(config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  return config
}, error => {
    console.log(error)
    Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(res => {
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
    // 获取错误信息
    const msg = errorCode[code] || res.data.msg || errorCode['default']
    // 二进制数据则直接返回
    if(res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer'){
      return res.data
    }
    if (code === 401) {
      let doms = document.getElementsByClassName('el-message-box')[0]
      if(doms === undefined){
        MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }
        ).then(() => {
          store.dispatch('LogOut').then(() => {
            location.href = '/index';
          })
        }).catch(() => {});
      }
      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
    } else if (code === 500) {
      Message({
        message: msg,
        type: 'error'
      })
      return Promise.reject(new Error(msg))
    } else if (code !== 200) {
      Notification.error({
        title: msg
      })
      return Promise.reject('error')
    } else {
      return res.data
    }
  },
  error => {
    console.log('err' + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    }
    else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    }
    else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    Message({
      message: message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename) {
  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob'
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      Message.error('无效的会话,或者会话已过期,请重新登录。');
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误,请联系管理员!')
    downloadLoadingInstance.close();
  })
}

export default service

这个里面的内容就丰富了,其中就引入了这么两个东西:

import axios from ‘axios’
 import { Notification, MessageBox, Message, Loading } from ‘element-ui’

哈哈,学到了!!!!!!!!!!
经过这么一看,后端接收的可以是json。