Socket
Socket
Sign inDemoInstall

@nuxtjs/axios

Package Overview
Dependencies
3
Maintainers
3
Versions
86
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.2 to 2.0.0

27

CHANGELOG.md

@@ -6,2 +6,29 @@ # Change Log

<a name="2.0.0"></a>
# [2.0.0](https://github.com/nuxt/modules/compare/@nuxtjs/axios@1.0.2...@nuxtjs/axios@2.0.0) (2017-06-09)
### Bug Fixes
* **axios:** install using Vue.use ([184651b](https://github.com/nuxt/modules/commit/184651b))
* **axios:** req typo ([16f28b1](https://github.com/nuxt/modules/commit/16f28b1))
* **axios:** use relative `API_URL` if same host and port else `API_URL` ([3421d19](https://github.com/nuxt/modules/commit/3421d19))
### Features
* **axios:** AXIOS_CREDENTIALS, AXIOS_SSR_HEADERS ([4dfdc2d](https://github.com/nuxt/modules/commit/4dfdc2d))
* **axios:** don't append optional config into env ([fe189e8](https://github.com/nuxt/modules/commit/fe189e8))
* **axios:** Easier API ([f54a434](https://github.com/nuxt/modules/commit/f54a434))
* **axios:** New API ([0194226](https://github.com/nuxt/modules/commit/0194226))
* **axios:** nuxt friendly errors for SSR ([65bc50f](https://github.com/nuxt/modules/commit/65bc50f))
### BREAKING CHANGES
* **axios:** API_PREFIX is deprecated.
<a name="1.0.2"></a>

@@ -8,0 +35,0 @@ ## [1.0.2](https://github.com/nuxt/modules/compare/@nuxtjs/axios@1.0.0...@nuxtjs/axios@1.0.2) (2017-05-29)

51

index.js
const chalk = require('chalk')
const path = require('path')
const { URL } = require('url')
module.exports = function nuxtAxios(options) {
// Register plugin
this.addPlugin({src: path.resolve(__dirname, 'plugin.js'), options})
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'
// API URL
const API_URL = options.API_URL || process.env.API_URL || 'http://localhost:3000'
process.env.API_URL = API_URL
module.exports = function nuxtAxios (moduleOptions) {
// Apply defaults
const options = Object.assign({
baseURL: process.env.API_URL || `http://${host}:${port}/api`,
browserBaseURL: null,
credentials: true,
proxyHeaders: true
}, this.options.axios, moduleOptions)
// API URL for Browser
const API_URL_BROWSER = options.API_URL_BROWSER || process.env.API_URL_BROWSER || API_URL
process.env.API_URL_BROWSER = API_URL_BROWSER
if (process.env.API_URL) {
options.baseURL = process.env.API_URL
}
// Common API Prefix
const API_PREFIX = options.API_PREFIX || process.env.API_PREFIX || '/api'
process.env.API_PREFIX = API_PREFIX
if (process.env.API_URL_BROWSER) {
options.browserBaseURL = process.env.API_URL_BROWSER
}
// Don't add env to production bundles
if (process.env.NODE_ENV !== 'production') {
this.options.env.API_URL = API_URL
this.options.env.API_URL_BROWSER = API_URL_BROWSER
if (!options.browserBaseURL) {
const url = new URL(options.baseURL)
const sameHost = url.host === `${host}:${port}`
options.browserBaseURL = sameHost ? url.pathname : options.url
}
printURL('API URL', API_URL, API_PREFIX)
// Register plugin
this.addPlugin({
src: path.resolve(__dirname, 'plugin.js'),
options
})
if (API_URL_BROWSER !== API_URL) {
printURL('API URL (Browser)', API_URL_BROWSER, API_PREFIX)
}
}
function printURL(title, url, prefix) {
/* eslint-disable no-console */
console.log(chalk.bgMagenta.black(` ${title} `) + chalk.magenta(` ${url}${prefix}`) + '\r\n')
console.log(`[AXIOS] Base URL: ${chalk.green(options.baseURL)} , Browser: ${chalk.green(options.browserBaseURL)}`)
}
module.exports.meta = require('./package.json')
{
"name": "@nuxtjs/axios",
"version": "1.0.2",
"version": "2.0.0",
"license": "MIT",

@@ -5,0 +5,0 @@ "main": "index.js",

import Axios from 'axios'
import Vue from 'vue'
const inBrowser = typeof window !== 'undefined'
const axiosPlugin = {
install() {
if(Vue.__nuxt_axios_installed__) {
return
}
Vue.__nuxt_axios_installed__ = true
const API_URL = inBrowser ? (process.env.API_URL_BROWSER || '') : (process.env.API_URL || 'http://localhost:3000')
// Try to get axios from components context, fallback to global Axios else
function getAxios() {
return (this && this.$root && this.$root.$options.$axios) ? this.$root.$options.$axios : Axios
}
// Vue Component Mixins
Vue.mixin({
computed: {
$axios() {
return getAxios.call(this)
// Make `this.$axios` available
if (!Vue.prototype.hasOwnProperty('$axios')) {
// Add mixin to add this._axios
Vue.mixin({
beforeCreate () {
// Check if `axios` has been defined in App
// Then fallback to $root.$axios
// Finally use global instance of Axios
this._axios = this.$options.axios || this.$root.$axios || Axios
}
})
// Add this.$axios instance
Object.defineProperty(Vue.prototype, '$axios', {
get () {
return this._axios
}
})
}
},
methods: {
// opts
$request(opts) {
return getAxios.call(this).request(opts);
},
// url, opts
$get(url, opts) {
return getAxios.call(this).get(url, opts);
},
$delete(url, opts) {
return getAxios.call(this).delete(url, opts);
},
$head(url, opts) {
return getAxios.call(this).head(url, opts);
},
// url, data, opts
$post(url, data, opts) {
return getAxios.call(this).post(url, data, opts);
},
$put(url, data, opts) {
return getAxios.call(this).put(url, data, opts);
},
$patch(url, data, opts) {
return getAxios.call(this).patch(url, data, opts);
}
}
})
// Send credentials only to relative and API Backend requests
const withCredentials = config => {
if (config.withCredentials === undefined) {
if (!/^https?:\/\//i.test(config.url) || config.url.indexOf(process.env.API_URL_BROWSER) === 0 || config.url.indexOf(process.env.API_URL) === 0) {
config.withCredentials = true
}
// Vue Component Mixins
Vue.mixin({
methods: {
// opts
$request (opts) {
return this.$axios.request(opts);
},
// url, opts
$get (url, opts) {
return this.$axios.get(url, opts);
},
$delete (url, opts) {
return this.$axios.delete(url, opts);
},
$head (url, opts) {
return this.$axios.head(url, opts);
},
// url, data, opts
$post (url, data, opts) {
return this.$axios.post(url, data, opts);
},
$put (url, data, opts) {
return this.$axios.put(url, data, opts);
},
$patch (url, data, opts) {
return this.$axios.patch(url, data, opts);
}
}
})
}
return config
}
// Nuxt friendly http errors
const handleError = error => {
// const response = error.response || {}
// const config = error.config || {}
// TODO: Add integration with vue notification and nuxt.$error
// Avoid promise rejections in SSR context
return inBrowser? Promise.reject(error) : error
}
Vue.use(axiosPlugin)
// Set requests token
function setToken(token, type = 'Bearer') {
function setToken (token, type = 'Bearer') {
if (!token) {

@@ -76,17 +73,66 @@ delete this.defaults.headers.common.Authorization;

export default ({app}) => {
// Nuxt friendly error handler
function errorHandler(error) {
if (error.response) {
// Error from backend (non 2xx status code)
if (error.response.status === 401) {
return this.redirect('/login')
}
error.statusCode = error.statusCode || parseInt(error.response.status) || 500
error.message = error.message || error.response.statusText || (error.statusCode + ' (Internal Server Error)')
} else if (error.request) {
// Error while making request
error.statusCode = error.statusCode || 500
error.message = error.message || 'request error'
} else {
// Something happened in setting up the request that triggered an Error
error.statusCode = 500
error.message = error.message || 'axios error'
}
// Display error page on unhandled promises
if(process.browser) {
return Promise.reject(error)
} else {
// Don't throw unhandled promises in SSR context
return this.app._nuxt.error.call({$options: this.app}, {
message: error.message,
statusCode: error.statusCode
})
}
}
export default (ctx) => {
const { app, store, req } = ctx
// Create new axios instance
const baseURL = process.browser
? (process.env.API_URL_BROWSER || '<%= options.browserBaseURL %>')
: (process.env.API_URL || '<%= options.baseURL %>')
const axios = Axios.create({
baseURL: API_URL + (process.env.API_PREFIX || '/api')
baseURL,
<% if(options.proxyHeaders) { %>headers: (req && req.headers) ? req.headers : {} <% } %>
})
<% if(options.credentials) { %>
// Send credentials only to relative and API Backend requests
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
});
<% } %>
// Setup instance interceptors
axios.interceptors.request.use(withCredentials);
axios.interceptors.response.use(undefined, handleError);
// Error handler
axios.interceptors.response.use(undefined, errorHandler.bind(ctx));
// Make accessible using {this,$nuxt}.$root.$options.$axios
// Make accessible using *.$axios
app.$axios = axios
store.$axios = axios
ctx.$axios = axios
// setToken helper
// token helper for authentication
axios.setToken = setToken.bind(axios)
}
# Axios
This plugin is a wrapper around [axios](https://github.com/mzabriskie/axios).
> Use [axios](https://github.com/mzabriskie/axios) with deep Nuxt integration and no pain!
- Sets default base URL.
- Handles all HTTP exceptions and prevents server side unhandled promise exceptions.
- Automatically set base URL for client & server side
- Injects `$get`,`$post`,... into vue context instances so requests can be done easily.
- Exposes `setToken` function to `$axios` so we can easily and globally set authentication tokens.
- Throws *nuxt-friendly* exceptions.
- Automatically enables `withCredentials` when requesting to default base URL.
- Throws *nuxt-friendly* exceptions and prevent SSR crashes.
- Automatically enables `withCredentials` when requesting to base URL.
- Proxy request headers in SSR.

@@ -22,6 +22,6 @@ ## Setup

### Inside `asyncData`
### Component `asyncData`
```js
async asyncData({app: {$axios}}) {
const {data} = await $axios.get('http://icanhazip.com')
async asyncData({ app }) {
const {data} = await app.$axios.get('http://icanhazip.com')
return {

@@ -33,4 +33,20 @@ ip: data

### Inside component methods
### Component mixins
You can always access axios instance using `this.$axios`.
This mixins are available for easier usage:
- `$request`
```js
this.$request({url: 'http://example.com')
```
- `$get`, `$delete`, `$head`
```js
this.$get('http://example.com')
```
- `$post`, `$put`, `$patch`
```js
this.$post('http://example.com', { foo: 'bar' })
````
Example:
```js
async mounted() {

@@ -42,10 +58,110 @@ const {data} = await this.$get('http://icanhazip.com')

## Customization
### Store `nuxtServerInit`
```js
async nuxtServerInit ({ commit }, { app }) {
const { data } = await app.$axios.get('http://icanhazip.com')
commit('SET_IP', data)
}
```
Customization can be done using shared environment variables.
### Store actions
If you need axios instance in store actions, you may have to pass it when dispatching.
Environment variable | Default | Description
---------------------|-------------------------|--------------------------------------------
API_URL | http://localhost:3000 | Base url for ajax requests in server-side
API_URL_BROWSER | [API_URL] | Base url for ajax requests in client-side
API_PREFIX | /api | Adds this prefix before all relative urls
```js
// In components
export default {
methods: {
updateIP() {
this.$store.dispatch('getIP', { $axios: this.$axios })
}
}
}
// In store
{
actions: {
async getIP ({ commit }, { $axios }) {
const { data } = await $axios.get('http://icanhazip.com')
commit('SET_IP', data)
}
}
}
```
## Options
You can pass options using module options or `axios` section in `nuxt.config.js`:
### `baseURL`
- Default: `http://[HOST]:[PORT]/api`
Base URL is required for requests in server-side & SSR and prepended to all requests with relative path.
You can also use environment variable `API_URL` which **overrides** `baseURL`.
### `browserBaseURL`
- Default: `/api`
Base URL which is used in client side prepended to all requests with relative path.
You can also use environment variable `API_URL_BROWSER` which **overrides** `browserBaseURL`.
- If `browserBaseURL` is not provided it defaults to `baseURL` value.
- If hostname & port of `browserbaseURL` are equal to nuxt server, it defaults to relative part of `baseURL`.
So if your nuxt application is being accessed under a different domain, requests go to same origin and prevents Cross-Origin problems.
### `credentials`
- Default: `true`
Adds an interceptor to automatically set `withCredentials` config of axios when requesting to `baseUrl`
which allows passing authentication headers to backend.
### `proxyHeaders`
- Default: `true`
In SSR context, sets client request header as axios default request headers.
This is useful for making requests which need cookie based auth on server side.
Also helps making consistent requests in both SSR and Client Side code.
## Dynamic API Backend
Please notice that, `API_URL` is saved into bundle on build, CANNOT be changed
on runtime! You may use [proxy](../proxy) module for dynamically route api requests to different backend on test/staging/production.
**Example: (`nuxt.config.js`)**
```js
{
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
proxy: [
['/api', { target: 'http://www.mocky.io', pathRewrite: { '^/api': '/v2' } }]
]
}
```
Start Nuxt
```
[AXIOS] Base URL: http://localhost:3000/api | Browser: /api
[HPM] Proxy created: /api -> http://www.mocky.io
[HPM] Proxy rewrite rule created: "^/api" ~> "/v2"
```
Now you can make requests to backend: (Works fine in both SSR and Browser)
```js
async asyncData({app}) {
// Magically makes request to http://www.mocky.io/v2/59388bb4120000dc00a672e2
const {data: {nuxt} } = await app.$axios.get('59388bb4120000dc00a672e2')
return {
nuxt // -> 'Works!'
}
}
```
Details
- `'@nuxtjs/axios'`
- By default axios plugin sets base url to `http://[host]:[port]/api` which is `http://localhost:3000/api`
- `'/api': 'http://www.mocky.io/v2'`
- This line creates a server middleware to pass requests from `/api` to `http://www.mocky.io/v2`
- We used `pathRewrite` to remove `/api` from starting of requests and change it to `/v2`
- For more information and advanced usage please refer to [proxy](../proxy) docs.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc