when I ty yarn dev In server rendering Proxy is working fine. fetching data from API site api.server.com/api
But after yarn generate axios request is calling self server
current.example.com/api.
Why it is not working in dist html?
Is Proxy working only in server side? Please, help.
I have NuxtJS config:
/*
** Nuxt.js modules
*/
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
axios: {
proxy: true // Can be also an object with default options
},
proxy: {
'/api/': {
target: 'http://api.server.com/api',
pathRewrite: {'^/api/': ''}
},
changeOrigin: true
},
plugins axios.js
import axios from 'axios'
export default axios.create({
baseURL: '/api/',
responseType: 'json'
})
here I called that API like below index.vue
<script>
import axios from '~/plugins/axios'
export default {
mounted() {
this.loaded();
},
methods: {
loaded(){
const location = axios.get('/contact/contact_session.php').then((response) => {
console.log(response);
}).catch((err) => {
});
},
}
}
</script>
The proxy.js module only works in the development environment, in the production environment you must configure your web-server, preferably nginx, the proxy that takes your requests for example from the path "/ api / ..." and redirects it to the server you need.
Related
I try to start a nuxt3 program, now I want to set server proxy.
A request to http://localhost:3000/api/v1 is supposed to return a response from our backend server on http://39.98.58.238:8594 , but now it gives me a 404 page.
At first, I follow the vite.js docs to set nuxt.config.js file
nuxt.config.js
export default defineNuxtConfig({
...
vite: {
server: {
proxy: {
'/api': {
target: 'http://39.98.58.238:8594',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
},
}
},
})
page
<script setup>
async function test() {
await usefetch('/api/v1/xxx')
}
</script>
<template>
<div>
<button #click="test">check</button>
</div>
</template>
It didn't work, my request returned a 404 page.
Then I try to follow this issue: text, do not use vite proxy
nuxt.config.js
export default defineNuxtConfig({
nitro: {
devProxy: {
'/api/': {
target: 'http://39.98.58.238:8594/',
changeOrigin: true
}
}
}
})
But it's still not work. What can I do to solve the problem? Thanks!!!
export default defineNuxtConfig({
nitro: {
devProxy: {
"/devApi": {
target:"your url",
changeOrigin: true,
prependPath: true,
}
}
},
})
I am trying to test my serverMiddleware in nuxt which has API routes
It has a single route /api/v1/test which returns a json true
My api/index.js file
import express from 'express'
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.get('/test', (req, res) => res.json(true))
export default {
path: '/api/v1',
handler: app,
}
Here is my api.spec.js file which contains the test returning 404
If I test my route / it returns a 200
My test/backend/api.spec.js file
import { resolve } from 'path'
import { Nuxt, Builder } from 'nuxt'
import supertest from 'supertest'
// We keep the nuxt and server instance
// So we can close them at the end of the test
let nuxt = null
// Init Nuxt.js and create a server listening on localhost:4000
beforeAll(async () => {
const config = {
dev: process.env.NODE_ENV !== 'production',
rootDir: resolve(__dirname, '../', '../'),
mode: 'universal',
}
nuxt = new Nuxt(config)
await new Builder(nuxt).build()
await nuxt.server.listen(3000, 'localhost')
}, 30000)
// Close server and ask nuxt to stop listening to file changes
afterAll(() => {
nuxt.close()
})
describe('GET /api/v1/test', () => {
test('returns status code 200', (done) => {
supertest(nuxt.server.app).get('/api/v1/test').expect(200, done)
})
})
My jest.config.js file
module.exports = {
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1',
'^~/(.*)$': '<rootDir>/$1',
'^vue$': 'vue/dist/vue.common.js',
},
moduleFileExtensions: ['js', 'vue', 'json'],
transform: {
'^.+\\.js$': 'babel-jest',
'.*\\.(vue)$': 'vue-jest',
},
collectCoverage: true,
collectCoverageFrom: [
'<rootDir>/components/**/*.vue',
'<rootDir>/pages/**/*.vue',
],
}
Can someone kindly suggest why the test is failing
In my case, it was because of the jest configuration.
my jest.config.js
testEnvironment: 'jsdom'
api.test(spec).file requires node environment.
I didn't modify it. Instead, I modified the api.test.js file.
I just added the comment code below at the head of the file.
solved) my api.test.js
/**
* #jest-environment node
*/
link : https://jestjs.io/docs/configuration#testenvironment-string
How can I prevent CORS issue with vue axios?
Following is the code for making requests with the backend using vue and axios.
axios.config.js
/// here I'm creating a vue axios instance.
import axios from "axios";
export default axios.create({
baseURL: "https://example.com/api/v1/",
headers: {
Accept: "application/json",
Authorization: "TOKEN 3413413dfdsfsafd3rr41",
},
});
and inside the vue.config.js
I've proxied the request.
module.exports = {
devServer: {
proxy: {
"/api/*": {
target: "http://localhost:8081",
secure: false,
changeOrigin: true,
},
},
},
};
and inside my vuex store I'm calling an action:
import axios from 'axios.config'
actions: {
getData({ commit }) {
axios
.get(`products/grocery`)
.then((res) => {
console.log("res :", res);
commit("SET_DATA", res.data);
})
.catch((e) => {
console.log("e :", e);
commit("SET_ERROR", e);
});
},
}
But when I look at the request in the console, I can see that it is sending request to the original url https://example.com/api/v1/ rather than appending the dev server line this: http://localhost:8081/api/v1/
Not sure why the proxying is not working!
External URLs doesn't get proxied. Change the base URL in axios to /api/v1/
export default axios.create({
baseURL: "/api/v1/",
headers: {
Accept: "application/json",
Authorization: "TOKEN 3413413dfdsfsafd3rr41",
},
});
Nuxt provides a proxy option which you can use to avoid cors errors,
Nuxt Documentation
You can refer this for more information and available options #nuxt/proxy
I have recently added axios to a file called services.js so it's better organised. This file is on my root folder.
#/services.js
import axios from "axios";
const axiosInstance = axios.create({
baseURL: " server url here",
});
export const api = {
get(endpoint) {
return axiosInstance.get(endpoint);
},
post(endpoint, body) {
return axiosInstance.post(endpoint, body);
},
};
Then I have a component called Post.vue in my view folder:
<template>
<section>
<div>
<ul></ul>
</div>
</section>
</template>
<script>
import { api } from "#/services.js";
export default {
name: "Post",
props: ["id"],
data() {
return {
post: null,
};
},
methods: {
getPost() {
api.get(`/post/${this.id}`).then(response => {
this.post = response.data;
console.log(this.post);
});
},
},
created() {
this.getPost();
},
};
</script>
<style></style>
I also have a router.ts file with all my routes:
import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";
import Home from "../views/Home.vue";
import Podcasts from "../views/Podcasts.vue";
import Post from "../views/Post.vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{
path: "/",
name: "home",
component: Home,
},
{
path: "/podcasts",
name: "podcasts",
component: Podcasts,
},
{
path: "/post/:id",
name: "post",
component: Post,
props: true,
},
],
});
export default router;
It's giving me a dependency error like #/services.js did not exist.
Unsure what's wrong at this stage.
Thanks a lot in advance for helping out
In a standard Vue CLI project, the # symbol resolves to /src
If your file is in the root of your project try
import { api } from '#/../services'
But personally, I'd move it into src
You can check the Webpack configuration using
vue inspect
Look for the resolve.alias rules.
Check your webpack configuration, depends on the version of webpack you have, there should be an alias # like this:
const path = require('path');
module.exports = {
//...
resolve: {
alias: {
"#": path.resolve(__dirname) // check the path here
}
}
};
Or if you are using vue.config.js
configureWebpack: {
name: name,
resolve: {
alias: {
'#': path.resolve(__dirname)// check the path here
}
}
},
Make sure the path is correctly set up. You mentioned you have another project working fine, which makes it a good reference.
I am beginner in the PWA and I try to get my code to call an API and then store it in the browser's cache. But I see that axios uses the XMLHttpRequest and not the fetch API, so I can't cache my API call.
I use workbox for the service worker and vue cli.
my service-worker.js :
workbox.setConfig({
debug: false,
});
workbox.precaching.precacheAndRoute([]);
//image in cache
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.staleWhileRevalidate({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
}),
);
//network request in cache
workbox.routing.registerRoute(
new RegExp('http://api.giphy.com/v1/gifs/'),
workbox.strategies.networkFirst({
cacheName: 'api',
}),
);
//js and css in cache
workbox.routing.registerRoute(
/\.(?:js|css)$/,
workbox.strategies.staleWhileRevalidate(),
);
//webfont in cache
workbox.routing.registerRoute(
new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
workbox.strategies.cacheFirst({
cacheName: 'googleapis',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 30,
}),
],
}),
);
my registerServiceWorker.js :
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('content in cached');
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
and my call API :
import Vue from 'vue';
import CONSTANTS from '../constants/constants';
import exception_manager from 'exception_manager';
export default {
getGiphy() {
return Vue.axios.get(`${CONSTANTS.SERVER_ADDRESS}search?q=cat&api_key=${CONSTANTS.API_KEY}&limit=9`).catch(error => {
exception_manager.handleException(error, 'GiphyService.js', 8, window, CONSTANTS.ERROR_SERVER_ADDRESS);
});
}
}
I think that's really the story with the xmlhttprequest, but I'm not sure.
On the other hand, js, css and images files are well cached
Your RegExp route inside of the service worker looks for http://api.giphy.com/v1/gifs/, which is an http: URL. Service workers will only intercept secure requests, which means https: (or http://localhost).
Make sure that you're using https: in your client-side Vue code, and adjust your Workbox configuration to use https: as well.