nuxt-community / axios-module Goto Github PK
View Code? Open in Web Editor NEWSecure and easy axios integration for Nuxt 2
Home Page: https://axios.nuxtjs.org
License: MIT License
Secure and easy axios integration for Nuxt 2
Home Page: https://axios.nuxtjs.org
License: MIT License
Just questioning whether these two useful features should be true
by default - I found they caused problems with my setup. As a noob or someone switching from the regular axios
module they introduce implicit complexity which can take a while to debug (vs. time saved from the benefits).
At lease a note regarding proxyHeaders
:
If directing requests at a url protected by CloudFlare's CDN you should set this to
false
to prevent CloudFlare from mistakenly detecting a reverse proxy loop and returning a 403 error.
@nuxt/axios
: 4.3.0i had defined the axios call request in methods
,it always return as TypeError: Cannot read property 'get' of undefined
all these code as below:
package.json
file:
{
"name": "axios-error",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@nuxtjs/axios": "^4.3.0",
"@nuxtjs/proxy": "^1.1.2",
"nuxt": "^1.0.0-rc11"
},
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start"
}
}
pages\index.vue
file content:
<template>
<div>
<ul>
<li v-for="blognew in blognews" :key="blognew.group_id">
{{blognew.group_id}}-{{blognew.title}}
</li>
</ul>
</div>
</template>
<script>
export default {
data: () => {
return {
blognews: []
}
},
created() {
this.fetchdata()
},
methods: {
fetchdata: async () => {
const url = '/api/pc/focus/'
let data = (await this.$axios.get(url)).data
this.blognews = data.data.pc_feed_focus
}
}
}
</script>
nuxt.config.js
file content:
module.exports={
modules:[
['@nuxtjs/axios',{debug:true}]
['@nuxtjs/proxy',['/api', { target: 'http://www.toutiao.com', pathRewrite: { '^/api': '/api' } }]]
]
}
any update for this bad issue , and I found that if i move the fetchdata
code into created
,it will work very well.
thanks.
Suddenly getting this warning a bunch of times after building. I don't know how $delete could be conflicting with other methods. I haven't added any $delete methods myself, and have not added any other modules or plugins that could be causing this issue. When I remove @nuxtjs/axios
, which is my only module at the moment, the error disappears. And there's also no $delete method on the instance anymore.
// In store
{
actions: {
async getIP ({ commit }, { axios }) {
const ip = await axios.$get('http://icanhazip.com')
commit('SET_IP', ip)
}
}
}
It seems to me there is error in documentation, because second argument of action is payload, payload does not contain axios
Hello,
In my project, we use Nuxt and the Axios module, and we have different environments (local, staging, prod...). We would like to build once the application, and deploy it everywhere, on any environment.
Today we cannot build only once because we have different API_URL
and API_URL_BROWSER
values, depending on the environment, and necessary for the nuxt build
phase.
So, on each server, we have to build and start, instead of just starting the same application everywhere.
For example, today we have to do:
API_URL=http://staging.api.url/ API_URL_BROWSER=http//staging.api.url.browser/ npm run build && npm start
on staging environment, and API_URL=http://prod.api.url/ API_URL_BROWSER=http//prod.api.url.browser/ npm run build && npm start
on prod environment.
Is there a way to build the application only once, and use the API_URL
and API_URL_BROWSER
variables when starting the application?
For example, we would like to do:
npm run build
only once, without any variable, and just API_URL=http://staging.api.url/ API_URL_BROWSER=http//staging.api.url.browser npm start
on staging environment, and API_URL=http://prod.api.url/ API_URL_BROWSER=http//prod.api.url.browser npm start
on prod environment.
I saw the Dynamic API Backend documentation, which use the @nuxtjs/proxy
module, but I was wondering if there is another way.
Thanks!
I would like to use nuxtjs/axios from nuxt.js (vue.js).
first,
npm install nuxtjs/axios
Then set nuxt.config.js.
modules: [ ['@ nuxtjs/axios', { baseURL: 'http://localhost: 4000', browserBaseURL: '/api', }], ]
Start the app.
npm run dev
And,
[AXIOS] Base URL: http: // localhost: 3000 /, Browser: /
Why can not I see the above message?
I think because of this,
There is a problem with asyncData () {}.
browserBaseURL: '/ api' does not work.
One good place to put some global error handlers is on the responseInterceptor, but looks like it is not being called when the request errors.
responseInterceptor: (response, { store, redirect }) => {
console.log('response', response)
if (response.status.code == 401) {
store.dispatch('logout')
redirect('/login')
}
return response
}
using version: 4.3.0
I could not find an accurate way to introduce and use axios
In my code:
nuxt.config.js
modules: [
'@nuxtjs/proxy',
'@nuxtjs/axios'
],
proxy: {
'/api/**': 'http://127.0.0.1:8000'
},
axios: {
requestInterceptor: (config, { store }) => {
if (store.state.token) {
config.headers.common['Authorization'] = `JWT ${store.state.token}`
}
return config
}
},
login.vue
import { mapActions } from 'vuex'
methods: {
...mapActions([
'login'
]),
handleLogin () {
this.login({ user: this.formData, axios: this.$axios })
}
}
store/index.js
actions: {
async login ({ commit }, { user, axios }) {
try {
const response = await axios.post('/account/login/', user)
const data = response.data
commit('INIT', data)
return Promise.resolve()
} catch (error) {
return Promise.reject(error.response.data)
}
}
I wondered if I had to call axios in this way
Is there a simple way to call axios in index.js?
I tried:
store/index.js
actions: {
async login ({ commit }, user) {
try {
const response = await this.$axios.$post('/account/login/', user)
const data = response.data
commit('INIT', data)
return Promise.resolve()
} catch (error) {
return Promise.reject(error.response.data)
}
}
and:
login.vue
this.login(this.formData)
But i got TypeError: Cannot read property '$axios' of undefined
Is not what I missed some steps?Can let me know? Thanks!
modules: [
'@nuxtjs/axios',
],
Get Error
.nuxt/axios.js:133:2 (module.exports.webpack_exports.a)
.nuxt/index.js:115:51 ( _callee$)
internal/process/next_tick.js:188:7 (process._tickCallback)
axios.interceptors.response.use(undefined, errorHandler.bind(ctx));
// Inject axios to the context as $axios
inject('axios', axios)
// Setup axios helpers
setupHelpers(axios)
}
module.exports.__webpack_exports__.a@133:2
How to fix?
I've been looking at the best way of handling 401 with my static generated nuxt app and could use some guidance here.
I'm using Nuxt 1.0.0-rc8 and @nuxtjs/axios 4.0.0
I thought the best way to handle any unauthorized requests would be using a global catch by adding the following into nuxt.config
responseInterceptor: (response, { store }) => {
if (response.status === 401) {
store.dispatch('logoutUser')
}
return response
},
So anytime the API returns a 401, the site will dispatch the action logoutUser
.
For some reason though, this is not triggered when I make calls to axios which return a 401.
Should I try something else?
Also, on the first page load I ideally want to run one auth check against the API to check the validity of a token as well.
I thought about adding this into the middleware, running an axios request and then setting the store before everything is setup. This doesn't seem to work either.
Any help would be greatly appreciated!
I've noticed that this module is targeted for external APIs, but I have nginx proxy and load balancer, allowing redirects to different API servers along with Nuxt web server using one domain. Simplified example:
location / {
#Nuxt
proxy_set_header Host $host;
...
}
location /auth {
#Authentication server
proxy_set_header Host $host;
...
}
location /rest {
#REST API server
proxy_set_header Host $host;
...
}
So I don't have to specify a baseURL, instead I may use relative URLs on both client and server sides, just like this:
const headers = req && req.headers ? {...req.headers} : {}
const {data} = await axios.get('/rest/orders/my', {headers: headers})
But it will not work with axios-module, since it removing the Host header, which is proxied by nginx.
Hi,
I've got these settings in my nuxt.config.js:
axios: {
credentials: false,
debug: true,
redirectError: {
404: '/404'
}
}
However when visiting a page that doesn't exist, I do get the Nuxt page not found error but it doesn't redirect me to the 404
route.
Right now when the @nuxtjs/axios
module is installed, the electron starter repo silently fails.
I haven't been able to find out exactly why but I was able to successfully port over the main parts of the module (e.g. injecting it into nuxt and vue instance, setting up setHeader
helper) and have it work. Hopefully I'll have more time to come back and look into this if I need more of the code, but I'll open this issue in case anyone encounters the problem and wants more official support.
Hello,
I'd like to grab JWT out of cookie and set it to the axios instance as authorization, but this only works on server side. After initial load, subsequent AsyncData ajax requests throw an error that token is not given.
'check-auth.js' available in nuxt.config router as global middleware
import { getTokenFromCookie, getTokenFromLocalStorage } from '~/utils/auth'
import { setBearerToken } from '~/utils/axiosHeaders'
export default async function ({ isServer, store, req, app }) {
// If nuxt generate, pass this middleware
if (isServer && !req) return
const token = isServer ? getTokenFromCookie(req) : getTokenFromLocalStorage()
if (token) {
await setBearerToken(app, token)
await store.dispatch('auth/set_user')
}
}
Here I set the bearer token using the 'context.app' as axios instance.
async function setBearerToken(vm, token) {
return new Promise((resolve, reject) => {
vm.$axios.setToken(token, 'Bearer')
resolve(true)
})
}
async set_user({ commit }) {
try {
const { data } = await this.$axios.get('auth/user')
commit('SET_USER', data.data)
} catch (error) {
// Token doesn't work anymore, throw it out local storage
unsetToken()
}
},
Using this, the user loads perfectly and the initial data on the loaded page aswell, but when I navigate through the app, all asyncData axios requests fail because token is not set. My guess is that the axios instance is completely different on clientside and doen't have the bearer token. But how to solve this?
I used to set token in localstorage and load user after app has loaded, but this brought other issues. (For example if I load the account page (not navigate to it, but fresh refresh), I want to redirect to login page if not logged in using middleware. But if the token is in localstorage, the user is loaded after the middleware and always thinks a user is not logged in. Therefore always redirecting.
So I've read that other people use JWT in cookie to grab user beforehand, but this brings me to the above issue
Unfortunately,
I have following situation:
Thank in advance!
Hi, I'm trying to use the Performing multiple concurrent requests from axios, is it going to be available?
const res = await app.axios.all([
app.axios.$get('/api/brand', {params: {all: true}}),
app.axios.$get('/api/model', {params: {all: true}})
])
Thanks!
Is this possible?
I was inspecting the moduleOptions
but that doesn't seem to contain any reference to axios
// all of this code is inside /modules/static.js
module.exports = function static(moduleOptions) { ...
// moduleOptions.axios ??
OR trying to find it inside of this
this.axios // undefined
// tried this too...
module.exports = function static(moduleOptions, { app }) { ...
app.axios.$get // doesn't work
...
Also tried importing @nuxtjs/axios
but that is just the general package... not my instance
const axios = require('@nuxtjs/axios')
Hopefully I'm just missing something small!
Calling my development microservices with http://localhost/api the credentials cookies are sent. Setting it to production to run against https://api.server/api it doesn't send the cookies any more.
First I thought it was due to this, but by deactivating it in "plugin.template.js" it is still not working:
axios.interceptors.request.use(config => {
// if (config.withCredentials === undefined) {
// if (!/^https?:\/\//i.test(config.url) || config.url.indexOf(baseURL) === 0) {
config.withCredentials = true
// }
// }
return config
});
Can anyone give me a hint how you are calling your microservices api?
I am currently running this in nuxtServerInit if a token is available. Progressing a little further, I noticed that the token is no longer available from the client. Meaning I also need to run setToken
again from the client side. From which nuxt lifecycle stage should I set the token with $axios.setToken?
Assume the following Dockerfile
:
FROM node:alpine
ENV HOST=0.0.0.0
EXPOSE 3000
WORKDIR /usr/src/app
COPY package.json package-lock.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
RUN npm run build
ENV NODE_ENV=production
CMD npm start
Because I run npm run build
when the environment variables have not been applied. This would cause to use the nuxt.config.js
default value so not working as expected in the runtime. Because runtime is when environment variables are actually applied.
Do you have any solution for this?
Hello,
for first, thanks for providing these awesome modules :)
And then I have an idea, about a new module option: secure
secure
option:module.exports = {
modules: [ '@nuxtjs/axios' ],
axios: getAxiosConfigs()
}
function getAxiosConfigs () {
const port = process.env.PORT || process.env.npm_package_config_nuxt_port || 3000
const host = process.env.HOST || process.env.npm_package_config_nuxt_host || 'localhost'
const config = {}
if (process.env.NODE_ENV === 'production') {
config.baseURL = `https://${host}:${port}/api`
}
return config
}
secure
option:module.exports = {
modules: [ '@nuxtjs/axios' ],
axios: {
secure: process.env.NODE_ENV === 'production'
}
}
I'm using JWT and refresh token authentication in my app (API and frontend are on different domains):
errorHandler (error) {
var err = error.response;
var request = err.config;
if (err.status===401 && !request.__isRetryRequest ) {
request.__isRetryRequest=true;
return this.$axios.post('/users/refresh').then(res => {
this.$axios.defaults.headers.common['Authorization'] = res.data.token;
request.headers['Authorization'] = res.data.token;
if (!res.data.success) {
this.$axios.defaults.headers.common['X-Refresh-Token'] = '';
request.headers['X-Refresh-Token'] = '';
}
return this.$axios(request);
}).catch((e)=>{
this.$axios.defaults.headers.common['Authorization'] = '';
request.headers['Authorization'] = '';
})
} else {
}
}
But I need to pass the new token into the store, and (if possible) set it server-side. How to do it?
Upon a token_expired when I check /me
for authorization, or any route that requires authorization, I need to hit /refresh
to attempt to refresh my token, i gave it a shot using the errorHandler
like so:
axios: {
errorHandler (error) {
if (error.response.data && error.response.data.error === 'token_expired') {
console.log ('expired token, going after /refresh')
this.$axios.get('/refresh').then((res) => {
error.config.__isRetryRequest = true
return this.$axios(error.config)
})
}
}
},
But I had no luck since this.$axios
is undefined, any other way I can do this?
reqMethods.forEach(method => {
axiosExtraProto['$' + method] = function () {
return this[method].apply(this, arguments).then(res => {
if (isServer) { // set-cookie can't auto write cookie on SSR
const csrfKey = this.options['csrfKey'];
if (csrfKey) {
const csrfToken = parseCookie(res.headers['set-cookie'], this.option['csrfKey'])
this.setHeader(csrfKey, csrfToken)
}
}
return res && res.data
})
}
})
When using the axios module in nuxt.config.js like:
modules.exports = {
modules: [
'@nuxtjs/axios',
],
// axios module settings
axios: {
// allows our SSR instance to use headers in axios request
proxyHeaders: true,
credentials: true,
// baseURL: 'https://local.dev/',
// SSR Sets up the initial axios instance...
init(axios, context) {
axios.defaults.baseURL = context.env.api;
},
},
}
I am requesting data from my server at local.dev, from my express server frontend at local.dev:3000
When SSR makes the request, my cookies & session work fine through CORS with local.dev
However, when the browser loads, axios is no longer using same cookies/session as the SSR instance, and making a request to my local.dev server results in a new cookie/session each time
What is missing, to make the SSR version of axios work in the same manner as the browser version of axios? They're currently sending different headers.
i'm trying to set a global response interceptor,
responseInterceptor: (response, {
store
}) => {
if (response.data.message) {
store.dispatch('toast', response.data, {
root: true
})
}
return response
}
i'm getting this error,
how can i do it correctly ?
I apologize in advance if I'm missing something here, but when the frontend headers get copied into to the global headers, this is going to potentially have duplicate headers (Accept
vs accept
), right?
I noticed some of my requests on the Nuxt server side are being sent back from my Django API as HTML. After turning on debug, I see the headers as:
headers:
{ Accept: 'application/json, text/plain, */*',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
...
I'm guessing the lowercase accept
is the one being forwarded from the browser, but the capitalized Accept
is the one I actually want.
Should there be a better way to merge in the headers from the incoming request? Or maybe just the accept header should be ignored?
When using the axios.init()
function within nuxt.config.js
, creating a new https.Agent() is quite difficult.
Importing https to be used constantly returns https is undefined.
const https = require('https');
axios: {
init(axios, context) {
axios.defaults.httpsAgent = new https.Agent({ rejectUnauthorized: false });
},
},
https
will be undefined, and fail.
Importing https within the axios.init()
callback also fails.
Hello,
I've try to implement directly axios by the community module, but I've a problem.
To do my api request I need route params so I pass as parameters context
to asyncData to know request parameters. But it's seems that I can't pass {app}
to access to the module and context
for route params together.
Simple example :
async asyncData (context, {app}) {
console.log(context);
console.log(app);
const MyData = await app.$axios.$get(`my-api-url.com/categories/${context.route.params.slugName}`)
return {MyData}
}
context
log works, but app
log returns undefined
Thanks a lot !
Hi there, I am running a backend server that correctly expose a few headers such as access-token
. However I'm unable to access these headers using console.log(response.headers)
which result undefined
.
Chrome dev tools correctly display the requests:
Here is how my store action looks:
async signIn ({ commit, dispatch }, { axios, email, password }) {
try {
const response = await axios.$post('auth/sign_in', {
email: email,
password: password
})
console.log(response)
console.log(response.headers) // Undefined
dispatch('clearAuthError')
} catch (error) {
console.log(error)
dispatch('setAuthError', error.response.data.errors)
}
},
If I enable debug: true
in axios module then it will show as expected in console:
Is this an upstream problem? Please advice, cheers.
How might one go about configuring a custom paramsSerializer
for Axios? I'm working on an app that uses nested query string params and I need to use the qs
lib with a different arrayFormat
, but I'm not sure how to modify the global instance of Axios when using this module. What I'd like to do is something like:
axios: {
baseURL: process.env.API_URL,
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'brackets' })
}
}
I think this was brought up before this module was moved, but are there any plans for making the the axios instance a bit easier to use? More specifically, I thought I saw someone mention an idea about making store actions a bit easier to use, instead of passing down axios.
Ideally, I'd love to be able to just import
the instance and use it even outside of Nuxt. I'm not that familiar with the latest plugin system, but is there a way to get the current Nuxt app and import the plugins somehow?
🚨 You need to enable Continuous Integration on all branches of this repository. 🚨
To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.
Since we did not receive a CI status on the greenkeeper/initial
branch, we assume that you still need to configure it.
If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/
.
We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.
Once you have installed CI on this repository, you’ll need to re-trigger Greenkeeper’s initial Pull Request. To do this, please delete the greenkeeper/initial
branch in this repository, and then remove and re-add this repository to the Greenkeeper integration’s white list on Github. You'll find this list on your repo or organiszation’s settings page, under Installed GitHub Apps.
This doesn't seem to be working with the latest tag
{
actions: {
async getIP ({ commit }) {
const ip = await this.$axios.$get('http://icanhazip.com')
commit('SET_IP', ip)
}
}
}
if i revert to
import axios from '~/plugins/axios'
{
actions: {
async getIP ({ commit }) {
const ip = await axios.get('http://icanhazip.com')
commit('SET_IP', ip)
}
}
}
then it works again
I'm trying to do login stuff, i fetch the user data from wht users sign in/input to the login form using
axios.post('some_sign_url', userdata)
inside store action and i can't figured out how to redirect the users into like profile page with the /_username/profile
routes which is the _username
is must be dynamic, i think the documentation is not too clear for facing this kind of problem. I hope there's one example or maybe i didn't found tht example one..
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.