How to access backend after deploying website on Heroku? - reactjs

My backend runs on port 5000 on localhost. So obviously when I connect to the backend from the frontend using const socket = io.connect('http://localhost:5000') others around the world will not be able to access it. I've deployed the React App on Heroku.
[https://murmuring-reaches-27066.herokuapp.com/]
Copy ID button isn't working because I don't understand how to connect to the backend when it's on production mode.
My Backend code (Only included relevant code)
const express = require("express")
const http = require("http")
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: "https://murmuring-reaches-27066.herokuapp.com/",
methods: [ "GET", "POST" ]
}
})
Any help is appreciated.

Related

localhost:3000 This site can’t be reached after installing http-proxy-middleware

I am building a newsletter sign-up form that uses .netlify-lambda to send my form submission to Mailchimp. I installed http-proxy-middleware to help the front end find the netlify-lambda folder. After writing the proxy setup code below my React start script stopped working. It appears the proxy setup below is interfering with localhost:3000.
My proxy setup looks like this
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
console.log('Using proxy...')
app.use(proxy('/.netlify/functions/', {
target: 'http://localhost:9000/',
"pathRewrite": {
"^\\.netlify/functions": ""
}
}));
};
If the target is localhost:9000 why is it interfering with localhost:3000?
When I start my Lambda server it says: Lambda server is listening on 9000.
I am also getting this error when trying to compile my client app.
crbug/1173575, non-JS module files deprecated
Short answer (for #lachnroll and anyone who might be encountering the same problem):
Please use const { createProxyMiddleware } = require("http-proxy-middleware") and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , instead of using const proxy = require('http-proxy-middleware'); and app.use(proxy("/.netlify/functions/" ...)...) , it should work.
Long one:
I've come across the same "can't be reached" thing in a React project when using http-proxy-middleware(2.0.3), until I changed const proxy = require('http-proxy-middleware'); and proxy("/.netlify/functions/" ...) to const { createProxyMiddleware } = require("http-proxy-middleware"); and app.use(createProxyMiddleware('/.netlify/functions/' ...)...) , I think the proxy has been removed, see: https://github.com/chimurai/http-proxy-middleware#readme

Can't establish connection between React JS & Django Channels

I have a web app using Django Rest Framework and React. I am trying to add web sockets to it. I opted for Django channels as they are the most recommended.
However, I keep getting this error Firefox can’t establish a connection to the server at ws://localhost:3000/ws/canvas_data & then the socket is closed automatically.
Apparently, the connexion can not be maintained between the frontend & the backend. I tried several options in the Routing URLs but nothing worked.
Maybe the problem is in the port since the same is used by HTTP & ws.
This is my first time dealing with Django Channels so please excuse my lack of knowledge.
This is the consumer:
from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer
from time import sleep
import json
class WSConsumer(AsyncWebsocketConsumer):
async def connect(self):
print("CONNECTION IS NOW OPEN !!")
await self.accept()
for i in range(20): #The logic should be here, this is just an example to test
await self.send(json.dumps({"nom_rapport": "pv"}))
sleep(1)
async def disconnect(self, message):
print("CONNECTION IS NOW CLOSED !!")
pass
the asgi.py configuration:
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from django.urls import path
from Dashboard.consumers import WSConsumer
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Dashboard_sise.settings')
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': URLRouter([
path(r'ws/canvas_data/', WSConsumer.as_asgi()),
])
})
settings.py file:
INSTALLED_APPS = [
.....
'channels',
'rest_framework',
.....
]
WSGI_APPLICATION = 'Dashboard_sise.wsgi.application'
ASGI_APPLICATION = 'Dashboard_sise.asgi.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": ['redis://localhost:6379']
}
},
}
The WebSocket is declared like this:
componentDidMount(){
var socketPath = 'ws://localhost:3000/ws/canvas_data';
const Socket = new WebSocket(socketPath);
Socket.onopen = () => {
console.log('Socket is connected');
}
Socket.onmessage = (e) => { //Logic will be placed here
console.log("MESSAGE :", e.data);
this.setState({messages: e.data});
};
Socket.onclose = (e) => {
console.error('Chat socket closed unexpectedly');
};
}
The front end is running on port 3000, while the back is on port 8000.
Thank you in advance.
You have to start a server that supports sockets like daphne
daphne -b 0.0.0.0 -p 8001 django_project.asgi:application

Webpack dev server sockjs-node returns 404 error

I am running a simple Vue app with webpack that I created with the vue-cli. When I run the dev server wtih npm run serve, it shows several errors in the client console when using sockjs-node. I believe this module is used by webpack for hot reloading (HMR).
The first error is:
Access to XMLHttpRequest at 'http://192.168.1.4:8080/sockjs-node/info?t=1615330207390' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I can solve this in two ways by editing the devServer in my vue.config.js. The first method is by setting public: 'localhost:8080'; and the second is by setting headers: {'Access-Control-Allow-Origin': 'http://192.168.1.4:8080', 'Access-Control-Allow-Credentials': 'true'}.
In both cases, I then see the following two errors:
POST http://localhost:8080/sockjs-node/690/qvgqwbdo/xhr_streaming?t=1615330686134 404 (Not Found)
GET http://localhost:8080/sockjs-node/690/zympwfsc/eventsource 404 (Not Found)
How do I resolve these errors so that the hot reloader will connect?
In the function I set to devServer.before in my vue.config.js file, I created my own websockets using Socket.io on the same port as my devSever. When the function returned, the devServer could not use that port for websockets, so it failed to launch sockjs-node. Therefore, when the frontend client tried to connect to the devServer, the requests were going to my sockets, instead of the devServer sockets, and it was ignoring them. Hence the 404 errors.
Here is my original code:
// server.js
const { createServer } = require('http')
const io = require('socket.io')
const addSocketEvents = require('./socket-api')
const port = process.env.PORT || 8080
module.exports = {
port,
configure(app) {
// `app` is an instance of express
// add the websockets
const httpServer = createServer(app)
socket = io(httpServer, {
path: '/socket-api'
})
addSocketEvents(socket)
// starts the server
// cannot use app.listen() because that will not start the websockets
httpServer.listen(port)
}
}
// vue.config.js
const { port, configure } = require('./server')
module.exports = {
devServer: {
before: configure,
public: `localhost:${port}`,
},
}
To fix this issue, I needed to allow the devServer to use the original port for sockjs-node, and launch my sockets on a different port. However, because I need to use the same port in production (due to restrictions by my current hosting provider), I only want my sockets to use a different port when running the devServer. To do this, I simply created a different httpServer and launched it on a different port, then created a proxy in the devServer config for that port. In my configure function, I just check to see if it is running in dev or prod, and act accordingly.
My production server is a simple express instance which calls the same configure function after it is created. This allows me to put all my startup code in one place.
Here is my new code:
// server.js
const { createServer } = require('http')
const io = require('socket.io')
const addSocketEvents = require('./socket-api')
const port = process.env.PORT || 8080
const proxyPort = 8081
module.exports = {
port,
proxyPort,
configure(app) {
// `app` is an instance of express
// add the websockets
let httpServer, socketPort
if (process.env.NODE_ENV === 'development') {
httpServer = createServer()
socketPort = proxyPort
} else {
httpServer = createServer(app)
socketPort = port
}
// adds the socket-api to be used via websockets
socket = io(httpServer, {
path: '/socket-api'
})
addSocketEvents(socket)
// starts the server
httpServer.listen(socketPort)
}
}
// vue.config.js
const { port, configure } = require('./server')
module.exports = {
devServer: {
before: configure,
public: `localhost:${port}`,
proxy: {
'/socket-api': {
target: `http://localhost:${proxyPort}`,
ws: true
}
}
},
}

React build causes CORS error when there were no issues in development

I have built a React application (my first React application), and a C#.NET Core 3.1 Web API which serves data to the UI. I am deploying the API and the React application on the same server (Windows 10) with port 3030 for the API and port 3029 for the React build which was generated running the command "npm run build". The IIS site for the UI was pointed at the build directory.
In my development environment, running the application using the deployed API works and no proxy is needed. When deployed, my screen loads but no records are retrieved via the FETCH and instead there is a CORS error:
Access to fetch at 'http://localhost:3030/api/checking' from origin 'http://localhost:3029' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Why does this work when running out React in development out of Visual Studio Code with a hot load and why does this not work after the deployment? More importantly, how do I get this to work?
API code from Startup.cs
ConfigureServices method
services.AddCors(options => {
options.AddDefaultPolicy(builder => {
builder.WithOrigins(Configuration["AppSettings:CorsUrl"])
.AllowAnyHeader()
.AllowAnyMethod();
});
});
Configure method
app.UseCors();
AppSettings.js code
"AppSettings": {
"CorsUrl": "http://localhost:3029"
}
React
I am storing my url within an .env file at the root level as shown below.
REACT_APP_API_URL=http://localhost:3030/api/checking
React Fetch command
In my checking.js component, the data is loaded and a FETCH is performed.
const SERVER_URL=`${process.env.REACT_APP_API_URL}`
function Checking() {
const [rowData, setRowData] = useState([]);
const [newData, setNewData] = useState(initialState);
const [displayModal, setModalDisplay] = useState(false);
const columnDefinitions = Columns();
const rowDataRef = useRef(rowData);
useEffect(() => {
fetch(SERVER_URL)
.then((response) => response.json())
.then((rowData) => {
setRowData(rowData)
rowDataRef.current = rowData;
});
}, []);
.
.
.
You need to set the Access-Control-Allow-Origin header. try the following methods to solve this error.
1.Clear your cookies and add Access-Control-Allow-Origin': '*' by Mod Header extension and
try again to check the fix .
2.Try using a middle interface to control your request and guide them
into the special rules.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
It turns out that I noticed a component misbehaving (ag-grid) and that caused me to run npm update. Once that was complete, I redeployed the build and everything is now working. I believe the update 'fixed' the issue.

Stripe payments not going through with React JS

I was working with Stripe on a localhost and everything was working perfectly but when I try to switch all the keys to live and run it on Netlify, it seems the payments do not go through. It only shows up as a log in the stripe dashboard.
It seems to be the below block of code I'm having issues with.
fetch('/stripe-charge', {
method: 'POST',
body: JSON.stringify(bodyObject)
})
If I change the stripe address above to http://localhost:9000/stripe-charge, everything works perfectly. Am I just not targeting the folder properly?
Folder structure:
main site folder
- src
- components
- layouts
- pages
- images
- functions
- stripe-charge.js
As #Think-Twice mentioned, /stripe-charge should be served a server side API endpoint instead of a file names.
What you can do in to serve stripe-charge.js in express.js [0]
const express = require('express')
const app = express()
const port = 3000
app.post('/stripe-charge', (req, res) => {
// Move y=your stripe-charge.js logic
})
app.listen(port, () => console.log(Example app listening on port ${port}!))
And then follow Netlify docs to do the deployment[1]
[0] http://expressjs.com/en/starter/hello-world.html
[1] https://www.netlify.com/docs/

Resources