Unable to access ExpressJS endpoints NuxtJS app - javascript

I am fairly new to Nuxt and Vue. I have worked with React and Express before but I'm not sure if I'm missing a step specific to the Nuxt configuration.
I'm trying to GET data from an endpoint on my Express server, and it's working fine locally, but once I've deployed it, I'm having one of a couple of different errors. At first I was getting
Access to XMLHttpRequest at 'http://localhost:3000/ENDPOINT' from
origin 'https://APPNAME.herokuapp.com' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
I was able to get past this by installing the cors and #nuxtjs/proxy npm packages, adding app.use(cors()) to my server and adding a changeOrigin property to proxy in nuxt.config.js.. Now I'm getting a 404 when it tries to GET APPNAME.herokuapp.com/ENDPOINT.
I created a new test app using npx create-nuxt-app, choosing express as the custom server framework and setting up a test endpoint in server/index.js
app.get('/test', (req, res) => {
res.status(200).send('reached test')
})
In my nuxt view, I added a method:
runTest () {
this.$axios.$get('/test')
.then(success => console.log('success text:', success))
}
Again, this runs fine locally, but once deployed, I got the CORS issue until I added the cors package and changeOrder. Now getting the 404, it seems like I can't access my server's endpoints. Does anyone know anything about this?
Thanks in advance for any help!
UPDATE:
My nuxt.config.js file:
module.exports = {
mode: 'universal',
/*
** Headers of the page
*/
head: {
titleTemplate: '%s - ' + process.env.npm_package_name,
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
plugins: [
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'#nuxtjs/eslint-module',
'#nuxtjs/vuetify'
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
proxy: {
'/api/': {
target: 'http://localhost:3000/',
pathRewrite: {
'^/api/': ''
},
changeOrigin: true
}
},
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
},
/*
** vuetify module configuration
** https://github.com/nuxt-community/vuetify-module
*/
vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
dark: true,
themes: {}
}
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend (config, ctx) {
}
}
}
My server file:
const express = require('express')
const consola = require('consola')
const cors = require('cors')
const { Nuxt, Builder } = require('nuxt')
const app = express()
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
await nuxt.ready()
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
app.use(cors())
app.get('/test', (req, res) => {
res.status(200).send('reached test')
})
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()
This is mostly default nuxt scaffolding on my test app.
Thanks

Related

Why is vue failing to set my proxy for api routes?

I have a vue app I'm trying to connect to a flask api, all running on different ports on the same machine. My vue.config.js looks like this:
module.exports = {
// options...
devServer: {
public: 'localhost',
disableHostCheck: true,
proxy: {
'^/flask': {
target: 'http://localhost:8001',
pathRewrite: {'^/flask': '/'},
changeOrigin: true,
logLevel: "debug",
},
'/V2': {
target: 'http://localhost:8001',
changeOrigin: true,
pathRewrite: {'^/V2': ''}
},
}
}
}
where port 8001 is the port the flask is running on. Except the actual api requests from vue are being sent to port 9600 (and failing). For example:
fetchData() {
const path = '/flask/search';
console.log('Homepage recieved query')
if (this.queryform !== 'initVal') {
axios.post(path, this.queryform)
.then((res) => {
this.queryResult = res.data;
console.log('Homepage recieved results');
})
.catch((error) => {
console.log(error);
});
}
},
results in the error "Proxy error: Could not proxy request //search from ****:8002 to http://localhost:9600 (ECONNREFUSED)." *** is the ip address, omitting for privacy sake.
I know this an error within vue, I'm able to successfully use all the api routes on the flask app using my api testing program.
I can't find anywhere in the code where requests are sent to :9600, is there another configuration file I need to change?

Vue app shows blank when accessing through network on development mode. Seems like it's not rendering

I'm building a website using VueJs and it works perfect with no errors on the localhost, and I can access it locally in the same computer using the IP address as well. I used to be able to open the website within my network to test it using my phone with the IP address using port 8080. For some reason I can't do that anymore, my phone seems to be able to connect correctly because the console shows the firebase development warning but that's about it. It doesn't seem to be rendering the actual website since it shows blank.
last thing I remember installing before this happened was persistedState and I did so using npm like all the other plugins I use. I don't think this is causing the issue but I thought it was worth mentioning.
this is my Vue.config file:
const path = require("path");
module.exports = {
publicPath:
process.env.NODE_ENV === "production" ? "/metronic/vue/demo3/" : "/",
configureWebpack: {
resolve: {
alias: {
// If using the runtime only build
vue$: "vue/dist/vue.runtime.esm.js" // 'vue/dist/vue.runtime.common.js' for webpack 1
// Or if using full build of Vue (runtime + compiler)
// vue$: 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
},
chainWebpack: config => {
config.module
.rule("eslint")
.use("eslint-loader")
.tap(options => {
options.configFile = path.resolve(__dirname, ".eslintrc.js");
return options;
});
},
css: {
loaderOptions: {
postcss: {
config: {
path: __dirname
}
},
scss: {
prependData: `#import "#/assets/sass/vendors/vue/vuetify/variables.scss";`
}
}
},
transpileDependencies: ["vuetify"]
};
this is my main.js (i skipped all the imports):
router.beforeEach(async (to, from, next) => {
console.log("router");
const user = await authf.currentUser;
(user) ? await store.dispatch("fetchUserProfile", user) : "";
const requiresAuth = await to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = await store.state.userProfile;
if (isAuthenticated.email != null) {
(requiresAuth) ? next() : next("/Dashboard");
} else {
(requiresAuth) ? next("/Login") : next();
}
// reset config to initial state
store.dispatch(RESET_LAYOUT_CONFIG);
// Scroll page to top on every route change
setTimeout(() => {
window.scrollTo(0, 0);
}, 100);
});
let app;
authf.onAuthStateChanged(async(user) => {
if (user) {
await store.dispatch('fetchUserProfile', user)
}
});
new Vue({
router,
store,
i18n,
vuetify,
firebase,
axios,
render: h => h(App)
}).$mount("#application");
when I do npm run serve it gives me the local access through localhost:8080 and the network access through 192.168.1.137:8080 as it always has. I have access with no console errors in my computer, but the app wont render when accessing through network.

Next.js Express Custom Server { dev: true } loads forever (empty response) but production { dev: false } works

I am using a express custom server with next.js. Custom Server
I added the next app to my router under the path /custom/uibackend/next
const next = require('next')
const app = next({ dev: true, dir: './', conf: { } })
const handle = app.getRequestHandler()
module.exports = router => {
router.all('*', (req, res) => handle(req, res))
}
If i run my app and access the route in the browser it loads for a while and gives a empty response back.
There is just this one log i the console:
info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
If i build the app and set dev to false it works as expected and i can access the route and the pages.
const app = next({ dev: false, dir: './', conf: { } })
I used the following next.config.js file:
module.exports = {
basePath: '/custom/uibackend/next'
}
My /pages folder is in the root.
Thank you.
I have found the error.
I forgot to call app.prepare()
app.prepare().then(() => {
// add handle to router/app after app.prepare has finished
})

ECONNREFUSED when dispatch action in nuxtServerInit

I am converting my Nuxt application to SSR - because I want to use nuxtServerInit and asyncData. These are the steps I have taken to convert it.
Remove ssr: false from nuxt.config.js
Dispatch actions to initialize store's state in nuxtServerInit inside store/index.js
Now my nuxt.config.js looks like this
require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` });
export default {
router: {
base: "/app/",
},
target: "static",
head: {
// Some head, meta, link config
},
css: ["#/assets/scss/main.scss"],
styleResources: {
scss: ["#/assets/scss/*.scss", "#/assets/scss/main.scss"],
},
plugins: ["#/plugins/apiFactory.js"],
components: true,
buildModules: [
"#nuxtjs/eslint-module",
["#nuxtjs/dotenv", { filename: `.env.${process.env.NODE_ENV}` }],
],
modules: [
"bootstrap-vue/nuxt",
"#nuxtjs/style-resources",
["nuxt-sass-resources-loader", "#/assets/scss/main.scss"],
],
build: {
splitChunks: {
layouts: true,
},
},
};
And the store/index.js looks like this.
import axios from "axios";
export const state = () => ({
data: [],
});
export const mutations = {
setData(state, data) {
state.data = data;
},
};
export const actions = {
async nuxtServerInit({ dispatch }) {
// Before converting to SSR this action was dispatched in page/component that need this data
await dispatch("fetchData");
},
async fetchData({ commit }) {
const { data } = await axios.get("http://localhost:3030/my/api/path");
commit("setData", data);
},
};
export const getters = { /* some getters */ };
But after I restarted the development server - I was greeted with connect ECONNREFUSED 127.0.0.1:3030
These are the steps I've taken after that
Check if the API on localhost:3030 is running and accessible - It's running and accessible via direct URL and Postman
Comment out the // await dispatch("fetchData"); in nuxtServerInit - restarted the dev server - site is accessible again but without initial data.
So, I suspected that the action dispatched in nuxtServerInit cause the problem - If it is how do I fix this problem or where should I look into next? Please let me know, Thanks!
Additional Information
The API on localhost:3030 is Lumen version 7.2.2
The application will be deployed on shared hosting
The main reason is that nuxt can't connect to your host from where it resides.
In my case it is docker container where 127.0.0.1 is... the container! So you have to change baseUrl to actually accessible server from that container.
const axiosPlugin: Plugin = ({ $axios, isDev }) => {
if (isDev && process.server) $axios.setBaseURL('http://172.22.0.1:3000/api')
}
If you have your own server add your api domain in hosts file (in linux /etc/hosts)
127.0.0.1 api.domain.com
I was struggling for 2 days to understand why it wasn`t working and then it hit me pm2 server side has access only locally.
this happend becuse your axios baseURL port at nuxt.config.js not same with port of command yarn run dev
example right config of axios:-
1-
nuxt.config.js
axios: {
baseURL: 'http://localhost:5000',
},
then start server command must have --port with same axios port
yarn run dev --port 5000

react app browser proxy with http-proxy-middleware

I've got problem with proxy in react app.
Target: I've got two react apps, first app is on localhost:3000 and second on localhost:3001. What I want? => When in first app I'll click on:
<a href="/app2">
<button>Second App Open</button>
</a>
Then url will change from localhost:3000 into localhost:3000/app2 and second react app show what has got in url localhost:3001.
I imported http-proxy-middleware library and create in src direction file setupProxy.js and inside:
const {createProxyMiddleware} = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
createProxyMiddleware('/app2',{
target: 'http://localhost:3001',
changeOrigin: true,
prependPath: false,
secure: false,
logLevel: 'debug',
ws:true
})
);
app.listen(3000)
};
Anyone could help me with this?
Also I tried this code in setupProxy.js:
const express = require('express')
const {createProxyMiddleware} = require("http-proxy-middleware");
app = express()
app.use(
createProxyMiddleware('/app2',{
target: 'http://localhost:3001',
changeOrigin: true,
prependPath: false,
secure: false,
logLevel: 'debug',
ws:true
})
);
app.listen(3000)
But then I've received error that require(...) is not a function oraz that express is not a function, when I take express into {} then also occurs error.
I know it's late and I came across the same issue. Keeping what worked for me so that others can give it a try.This code is tested for react app created with create-react-app.
I proxied this endpoint - https://services.odata.org/V2/Northwind/Northwind.svc/Customers?$format=json
setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = (app) => {
app.use(createProxyMiddleware('/api2', {
target: 'https://services.odata.org/V2/Northwind/Northwind.svc/',
changeOrigin: true,
pathRewrite: { '^/api2': '' }
})
);
}
Your .js file
triggerCORSCall() {
axios.get(`/api2/Customers?$format=json`)
.then(response => {
alert('Success');
}).catch(error => {
alert('Failure');
console.log(error);
})
}

Categories