Heroku Deploy Vite Static App Won't Connect to API with Axios Using a Proxy - vue.js

I think this problem follows this one on netlify API from proxy not working after deploying on netlify
I am setting up a Vite app and making an axios api request in my app component
getSuggestionList(street, zip, city) {
this.axios.get('/1.0/address/find?country=at&zip=' + zip + '&city=' + city + '&street-address=' + street + '&street-number=&offset=1&limit=100', {
auth: {
username: '7166-631A-5394-4C03-9106-0A93-C433-2613',
password: ''
}
})
Now, for development I configured a proxy in server
in vite.config.js
import { fileURLToPath, URL } from "url";
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url)),
},
},
server: {
proxy: {
'/1.0/address': 'http://api.opendata.host/'
}
},
proxy: {
'/1.0/address': {
target: 'http://api.opendata.host/',
changeOrigin: true,
secure: false,
ws: true,
}
}
});
Following this guide
https://rubenr.dev/en/cors-vite-vue/
I understand this does not transfer to production, so I also tried the proxy part. I don't get a response, just like described in the netlify guide.
From Heroku docs
https://github.com/heroku/heroku-buildpack-static
I have the basic setup without proxies (leading to the initial, no-response behavior)
in static.json:
{
"root": "./dist",
"clean_urls": true,
"routes": {
"/**": "index.html"
},
"proxies": {
"/1.0/address": {
"origin": "http://api.opendata.host/"
}
}
}
And when I add proxies I get a 404 not found. When I change up the spelling: no response again, so it seems to be making a connection with the proxies configuration. But why not they way it works locally? Does anyone see my error here or having something for me to try?

I found it: for anyone else having trouble with this kind of deployment on Heroku -- the mountpoint "/1.0/address" in static.json seems to be replaced resulting in the 404 not found.
For production I added a prefix /api in my axios call, something like
var apiPath = '/1.0/address/find?country=at&zip=' + zip + '&city=' + city + '&street-address=' + street + '&street-number=&offset=1&limit=100'
var prodMountpoint = '/api' // /api/
if (import.meta.env.PROD) {
apiPath = prodMountpoint + apiPath
}
This results in a correct api call: "/api" is replaced with the proxied host, if I understand correctly. For development, the vite.config.js does its work as before.

Related

server does not connect to the right port for my DB when it makes a request

I am running a node/express react app, with mongoDB as my database, its being served on a EC2 instance AWS. I am using MobaXterm to ssh into my server. The problem I am encountering, when I go to signUp/Login, and it makes the http request, its not sending the Request to port:8081 where my DB is. My front end is being hosted on port:3000, as seen here url with port.
The home page of my app show display public content, but instead it shows this should display my content, instead displays html syntax. I am using PM2 to run both the front end and back end , they are 2 separate instances. Here is my ecosystem.config.js file that gets called to start the front end
module.exports = {
apps: [
{
name: 'frontend',
script: 'npx',
args: 'serve -s build -l 3000 -n',
interpreter: 'none',
env: {
NODE_ENV: 'production',
},
},
],
}
Here is my http-common.js file that sets up axios
import axios from 'axios';
const apiUrl = process.env.NODE_ENV === 'production' ? process.env.REACT_APP_PRODUCTION : process.env.REACT_APP_DEV;
export default axios.create({
baseURL: apiUrl,
headers: {
"Content-type": "application/json"
}
});
Here is where my public content on my home page is called
import http from '../http-common';
import authHeader from './auth-header';
class UserService {
getPublicContent() {
return http.get('api/test/all');
};
getUserBoard() {
return http.get('api/test/user', { headers: authHeader() });
};
getModeratorBoard() {
return http.post('api/test/mod', { headers: authHeader() });
};
getAdminBoard() {
return http.put('api/test/admin', { headers: authHeader() });
};
}
export default UserService;
and my .env.production file
REACT_APP_PRODUCTION=http://EC2-INSTANCE-URL-NOT-REAL:8081/
And you can see here that instead of the REQUEST using port:8081 it sends the request to port:3000
GET request to wrong port
**** Also my ports are open on 8081 , on the security group for the EC2 instance ***
Im new to the backend so im not sure what to do , or how to continue, I really want to have my project CI/CD working before I try to make any more progress.

Devserver Proxy w/ Axios

I cannot seem to get the devServer: proxy setting working in my vue / express app.
My vue.config.js file is in the root of my client folder and looks like:
module.exports = {
devServer: {
proxy: {
'api': {
target: 'http://localhost:5000'
}
}
},
transpileDependencies: [
'vuetify'
]
}
I'm sending a request from the frontend using axios like this:
const response = await http.get("/api/auth/authenticate");
My express app is running on localhost:5000 and I've configured endpoints as such:
...other endpoints
app.use("/api/auth", authController);
The request appears in my network tab as:
Request URL: http://localhost:8080/api/auth/authenticate
and returns a 404 error.
What am I missing here?
Since now it is not fetching from your backend, but searching for some static content (hitting 8080, vue must be running on this port). Try using, so that it get redirected to proxy:
proxy: {
'^/api': {
target: 'http://localhost:5000',
ws: false,
changeOrigin: true
},
Or just '/api' instead of '^/api'

Vue.js - proxy in vue.config.js is being ignored

I have been searching and reading thru documentation on this topic but I was unbale to make it work.
https://cli.vuejs.org/config/#devserver-proxy
I made my Vue.js application normaly by the commnand
vue create my-app
so I'm running the app by command
npm run serve
on http://localhost:8080/. Pretty standart stuff.
But my app needs a PHP backend which is running at https://localhost/
So I setted up the proxy setting in vue.confic.js file in my root directory.
Content of vue.confic.js file:
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'https://localhost/',
ws: true,
changeOrigin: true
}
}
}
};
And I'm trying to make axios call for the script on the adress
https://localhost/test.php
The axios call is
mounted() {
this.$axios.get('api/test.php', {})
.then(response => { console.log(response.data) })
.catch(error => { console.log(error) });
},
But for some reason which i cant figure out I'm still getting
GET http://localhost:8080/api/test.php 404 (Not Found)
Thank you in advance. I'll be happy for any tips.
Your axios call is going to make the request to the API with whatever protocol the webpage is on.
The error shows that you’re making an http call but your webpack config is only spoofing https. Are you visiting https from the page making the request?
Eg https://localhost:8080
You can also try updating your webpack proxy server to look like this
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'https://other-server.example.com',
secure: false
}
}
}
};
Additional debug steps: curl your Api endpoint from your terminal to see if it’s a protocol issue
you can try
https: true,
proxy: {
'/api': {
target: 'https://localhost/',
ws: true,
changeOrigin: true
}
}
before try, restart by npm run serve to make it sense

CORS axios Nuxt.js

I'm using an API with my Nuxt, here is my nuxt.config.js to allow the requests :
axios: {
prefix: '/api/',
proxy: true,
},
proxy: {
'/api/': {
target: process.env.API_URL || 'http://localhost:1337',
pathRewrite: {
'^/api/': '/',
}
},
}
On a specific page of my app, I need to send requests to another API from another domain. I'm using axios direclty in this Vue component :
axios.post('mysite.com/widget.rest')
As response, I obtain CORS error. Can I allow multiple API in my config ?
If you mean being able to access APIs under different URLs, AFAIK it's not possible out of the box. We tried adding proxy to different targets, but it only worked on client side, not during SSR.
What we ended up doing is having the default axios instance for our main API, and creating a plugin that creates extra axios instances for our other APIs for SSR.
Add extra "suburl" to proxy - this sorts out client side and means no CORS issues.
proxy: {
'/forum/': {
target: 'https://other.domain.com/',
pathRewrite: {'^/forum/': '/'}
},
'/api/': ...
},
For SSR to work, axios should hit directly the other API
import Vue from 'vue'
var axios = require('axios');
const forumAxios = axios.create(process.client ? {
baseURL: "/"
} : {
baseURL: 'https://other.domain.com/'
});
// this helps Webstorm with autocompletion, otherwise should not be needed
Vue.prototype.$forumAxios = forumAxios;
export default function (context, inject) {
if (process.server) {
forumAxios.interceptors.request.use(function (config) {
config.url = config.url.replace("/forum/", "");
return config;
}, function (error) {
return Promise.reject(error);
});
}
inject('forumAxios', forumAxios);
In components, you can then use something like:
async asyncData({app}) {
let x = await app.$forumAxios.get("/forum/blah.json");
You can use process.env prop of course instead of hardcoded URL.
This will hit https://other.domain.com/blah.json.

CORS blocking client request in Nuxt.js

I am having issues when making a client request.
I have followed the documentation on Nuxt.js and Axios but I still can't seem to get it working. Maybe I am missing something..
My Vue component calling the vuex action:
methods: {
open() {
this.$store.dispatch('events/getEventAlbum');
}
}
The action in vuex:
export const actions = {
async getEventAlbum(store) {
console.log('album action');
const response = await Axios.get(url + '/photos?&sign=' + isSigned + '&photo-host=' + photoHost);
store.commit('storeEventAlbum', response.data.results);
}
};
And my nuxt.js.config
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
axios: {
proxy: true
},
proxy: {
'/api/': {
target: 'https://api.example.com/',
pathRewrite: { '^/api/': '' }
}
}
Anybody who can help?
I believe the issue that #andrew1325 is trying to point out is that the API provider needs to have the CORS enabled, not just your server, without changing the headers in your proxy, you're passing the same headers, which at the moment prevent access.
It seems to me that you're only missing changeOrigin
please try the following config:
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
axios: {
proxy: true
},
proxy: {
'/api/': { target: 'https://api.example.com/', pathRewrite: {'^/api/': ''}, changeOrigin: true }
}
also make sure that your front-end API url is pointing to your proxied request /api