【问题标题】:Default query params not getting passed in axios request默认查询参数未在 axios 请求中传递
【发布时间】:2019-10-17 05:32:07
【问题描述】:

我正在使用 axios.create() 来传递一个 baseURL 和一些像这样的默认查询参数

axios.create({
    baseURL: 'http://somebigurlhere',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
   }
});

当我使用时

axios.get('/search', {
    params: {
        q: 'word'
    }
});

默认参数不会在 GET 调用中合并。

我得到的是 http://somebigurlhere/search?q=word

而不是 http://somebigurlhere/search?part=part&maxResults=5&key=key&q=asd

我尝试以许多其他方式进行配置,但仍然无法正常工作。 我在这里做错了吗?

我在其他项目中尝试过同样的方法,它在那里工作。刚刚使用 create-react-app 创建了一个新的 react 应用程序,这似乎不再起作用了。

【问题讨论】:

标签: javascript reactjs api axios create-react-app


【解决方案1】:

降级 axios 的版本。最新版本有一些问题

npm install --save axios@0.18.1

【讨论】:

【解决方案2】:

我用两种方法解决了:

  1. 在使用请求时使用默认参数并传播它们

    export const API_DEFAULT_PARAMS = {
      part: 'part',
      maxResults: 5,
      key: 'key'
    }
    
    export default axios.create({
      baseURL: 'http://somebigurlhere',
    });
    

    然后使用它:

    import api, { API_DEFAULT_PARAMS } from './place/where/previous/file/is';
        ....
    api.get('/search', {
       params: {
        // spread the default params
         ...API_DEFAULT_PARAMS,
        // add your own parameters here
         q: 'word',
       }
    });
    
  2. 按照用户在此处的建议使用拦截器

    const instance = axios.create({
      baseURL: 'http://somebigurlhere',
    }); 
    
    instance.interceptors.request.use(config => {
      config.params = {
       // add your default ones
       part: 'part',
       maxResults: 5,
       key: 'key',
       // spread the request's params
        ...config.params,
      };
      return config;
    });
    
    export default instance; 
    

    然后使用它

    import api from './place/where/previous/file/is';
    ...
    api.get('/search', {
     params: {
       q: 'word',
     }
    });
    

我更喜欢拦截器方法,因为它将默认参数抽象到实例文件本身,您不必每次使用实例时都导入和传播对象。

【讨论】:

  • 这应该被接受为正确答案。很好的解释和有用的!
  • 选项#2 中有一个小错误,用于拦截器。 ...config.params 必须位于末尾,以便它覆盖默认值,而不是其他方式。所以正确的定义应该是这样的:config.params = { ...defaults, ...config.params }
【解决方案3】:

只需创建一个配置对象并将其传递给您的 Axios.get 请求。

const config = {
    baseURL: 'www.someurl.com',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
    }

  }

axios.get('/waffles', config);

例子:

const config = {
    baseURL: 'https://reqres.in',
    params: {
        per_page: 3
    }
}

axios.get('/api/users?page=1', config).then(response => {console.log(response)}).catch(err => {console.log(err)});
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

如果您想使用 axios.create,您需要将其作为 axios 实例对象分配给一个变量,然后针对该实例运行您的请求。

var instance = axios.create({
    baseURL: 'https://reqres.in',
    params: {
        per_page: 5
    }
});
instance.get('/api/users?page=1').then(response => {console.log(response)}).catch(err => {console.log(err)});
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>


因此,正如我所说,对于您的确切示例,将 axios.create 分配给一个变量,然后从中发出您的 .get 。

var instance = axios.create({
        baseURL: 'http://somebigurlhere',
        params: {
            part: 'part',
            maxResults: 5,
            key: 'key'
        }
    });


instance.get('/search', {
    params: {
        q: 'word'
    }
});



更大的编辑 此编辑显示了如何在我的回答中对每个 OP 评论做出反应。可以在此处找到演示 htis 的实际沙箱: https://codesandbox.io/embed/cranky-aryabhata-2773d?fontsize=14

//axios_control.js 文件

import axios from "axios";
export const instance = axios.create({
  baseURL: "https://reqres.in",
  params: {
    per_page: 5
  }
});


// index.js 文件 记下从 axios_control 的导入以及在渲染之前记录返回数据的用法。

import React from "react";
import ReactDOM from "react-dom";
import { instance } from "./axios_control";

import "./styles.css";

function App() {
  instance.get("/api/users").then(response => {
    console.log(response);
  });

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

【讨论】:

  • 这是一个跨 react 应用的自定义配置。我认为在我提出请求的任何地方创建一个配置对象都不是一个好主意。第二部分是正确的,我正在导出似乎对我不起作用的实例
  • 如果反应应用程序中的配置相同,我不明白为什么不能从单个位置导出它。其次,我展示的第二种方式是使用 axios.create 的 axios 方式,如果您遇到问题,您在 yoru 代码中还有其他问题。
  • 我可以从一个位置导出它,但正如我在问题中提到的那样,它不起作用。它以前可以工作,但是对于我从 create-react-app 创建的新应用程序,这不再适合我了。导出显然有效,附加到网址的参数不起作用
  • @pdjinn 这是我在反应沙箱中的确切代码。 codesandbox.io/embed/cranky-aryabhata-2773d?fontsize=14 axios_control.js 正在导出我的对象。
  • 谢谢@basic。刚刚发现 axios v0.19.0 最近发布了,这段代码在那里不起作用。对于 v0.18.0,即使我的代码运行良好。
【解决方案4】:

使用应该返回一个像这样的自定义对象

const custom = axios.create({
    baseURL: 'http://somebigurlhere',
    params: {
        part: 'part',
        maxResults: 5,
        key: 'key'
   }
});

然后使用自定义对象发出请求

custom.get('/search', {
    params: {
        q: 'word'
    }
});

请在 codepen 中尝试类似的示例

然后您将在控制台中看到,查询参数在请求中合并在一起(蓝线),如下图

【讨论】:

  • 这与基本的答案有何不同?
  • Basic 的回答与我第一次回答时完全不同。我后来编辑了他的。
  • 尽管我相信我的答案更清晰直观,并带有图示。很抱歉,如果我没能看到你很好地表达你的答案。
  • 好吧,给你更多的力量
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2021-12-19
  • 2019-09-11
  • 2012-08-28
  • 1970-01-01
相关资源
最近更新 更多