Vue JS,Axios 重试请求。防止 JSON 引号

Vue JS, Axios retry request. Prevent JSON quotes

我有一个 axios 拦截器,用于需要用户获得授权的情况,但他没有。例如,因为令牌已过期。 现在,令牌刷新后,应重试原始请求。 但是,目前原始请求似乎已更改,因此服务器给我一个 JSON.parse 错误。

SyntaxError: Unexpected token " in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (/var/app/current/node_modules/body-parser/lib/types/json.js:158:10)
    at parse (/var/app/current/node_modules/body-parser/lib/types/json.js:83:15)
    at /var/app/current/node_modules/body-parser/lib/read.js:121:18
    at invokeCallback (/var/app/current/node_modules/raw-body/index.js:224:16)
    at done (/var/app/current/node_modules/raw-body/index.js:213:7)
    at IncomingMessage.onEnd (/var/app/current/node_modules/raw-body/index.js:273:7)
    at IncomingMessage.emit (events.js:314:20)
    at IncomingMessage.EventEmitter.emit (domain.js:483:12)
    at endReadableNT (_stream_readable.js:1241:12)

这是因为,而不是原来的请求,即JSON,它似乎再次处理它,把它放在引号等中,所以它变成了一个字符串和bodyparser,抛出上面的错误. 所以请求内容,变成:

"{\"traderaccount\":\"{\\"traderaccountID\\":\\"undefined\\",\\"traderID\\":\\"2\\",\\"name\\":\\"Conscientious\\",\\"order\\":99,\\"myFxLink\\":\\"\\",\\"myFxWidget\\":\\"\\",\\"copyFxLink\\":\\"83809\\",\\"tokenLink\\":\\"\\",\\"tradertext\\":{\\"tradertextID\\":\\"\\",\\"traderaccountID\\":\\"\\",\\"language\\":\\"\\",\\"commission\\":\\"\\",\\"affiliateSystem\\":\\"\\",\\"leverage\\":\\"\\",\\"mode\\":\\"\\",\\"description\\":\\"\\"},\\"accountType\\":\\"\\",\\"accountTypeID\\":1,\\"minInvest\\":2000,\\"currency\\":\\"\\",\\"currencySymbol\\":\\"\\",\\"currencyID\\":1,\\"affiliateSystem\\":1}\"}"

而不是

{"traderaccount":"{\"traderaccountID\":\"undefined\",\"traderID\":\"2\",\"name\":\"Conscientious\",\"order\":99,\"myFxLink\":\"\",\"myFxWidget\":\"\",\"copyFxLink\":\"83809\",\"tokenLink\":\"\",\"tradertext\":{\"tradertextID\":\"\",\"traderaccountID\":\"\",\"language\":\"\",\"commission\":\"\",\"affiliateSystem\":\"\",\"leverage\":\"\",\"mode\":\"\",\"description\":\"\"},\"accountType\":\"\",\"accountTypeID\":1,\"minInvest\":2000,\"currency\":\"\",\"currencySymbol\":\"\",\"currencyID\":1,\"affiliateSystem\":1}"}

来自axios原请求内容。 都是未格式化的请求内容,我在开发者网络控制台可以看到。

两种情况下的内容类型都是 application/json。

下面是拦截器代码:

    Axios.interceptors.response.use(
      (response) => {
        return response;
      },
      (err) => {
        const error = err.response;
        if (
          error !== undefined &&
          error.status === 401 &&
          error.config &&
          !error.config.__isRetryRequest
        ) {
          if (this.$store.state.refreshToken === "") {
            return Promise.reject(error);
          }
          return this.getAuthToken().then(() => {
            const request = error.config;
            request.headers.Authorization =
              Axios.defaults.headers.common[globals.AXIOSAuthorization];
            request.__isRetryRequest = true;
            return Axios.request(request);
          });
        }
        return Promise.reject(error);
      }
    );
  private getAuthToken() {
    if (!this.currentRequest) {
      this.currentRequest = this.$store.dispatch("refreshToken");
      this.currentRequest.then(
        this.resetAuthTokenRequest,
        this.resetAuthTokenRequest
      );
    }
    return this.currentRequest;
  }

  private resetAuthTokenRequest() {
    this.currentRequest = null;
  }

// store refreshToken
    async refreshToken({ commit }) {
      const userID = this.state.userID;
      const refreshToken = Vue.prototype.$cookies.get("refreshToken");
      this.commit("refreshLicense");
      commit("authRequest");
      try {
        const resp = await axios.post(serverURL + "/refreshToken", {
          userID,
          refreshToken,
        });
        if (resp.status === 200) {
          return;
        } else if (resp.status === 201) {
          const token = resp.data.newToken;
          const newRefreshToken = resp.data.newRefreshToken;
          Vue.$cookies.set(
            "token",
            token,
            "14d",
            undefined,
            undefined,
            process.env.NODE_ENV === "production",
            "Strict"
          );
          Vue.$cookies.set(
            "refreshToken",
            newRefreshToken,
            "30d",
            undefined,
            undefined,
            process.env.NODE_ENV === "production",
            "Strict"
          );
          axios.defaults.headers.common[globals.AXIOSAuthorization] = token;
          commit("authSuccessRefresh", { newRefreshToken });
        } else {
          this.dispatch("logout");
          router.push({
            name: "login",
          });
        }
      } catch (e) {
        commit("authError");
        this.dispatch("logout");
      }

那么,能不能帮我防止axios在重试的请求上更改请求内容。所以它不把它放在引号中并引用已经存在的引号?

感谢评论,我找到了解决方案。 在重新发送之前尝试解析内容:

axios.interceptors.response.use(
 (response) => response,
 (error) => {
 const status = error.response ? error.response.status : null;

 if (status === 401 && error.config && !error.config.__isRetryRequest) {
  return refreshToken(useStore()).then(() => {
    const request = error.config;
    request.headers.Authorization =
      axios.defaults.headers.common["Authorization"];
    request.__isRetryRequest = true;
    try {
      const o = JSON.parse(request.data);

      if (o && typeof o === "object") {
        request.data = o;
      }
    } catch (e) {
      return axios.request(request);
    }
    return axios.request(request);
  });
 }

 return Promise.reject(error);
});