My parse server is running on heroku and everything works great, and when I visit myapp.heroku.com I get the "I dream of being a website" text.
Question is, how do I run the web app in the public folder? I suspect I need to change something here...
app.get('/', function(req, res) {
res.status(200).send('I dream of being a parse server.');
});
ok I figured this out quick... but incase someone else also falls into this pit.
use:
app.use('/public', express.static(path.join(__dirname, '/public')));
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/public/index.html'));
});
also make sure you have express 4.8 or higher
Related
I am working on an app using a React frontend and Express backend, with GraphQL setup through Apollo (I am following and modifying tutorial https://www.youtube.com/playlist?list=PLN3n1USn4xlkdRlq3VZ1sT6SGW0-yajjL)
I am currently attempting deployment, and am doing so with Heroku. Everything functions perfectly on my local machine before deployment and on Heroku in Google Chrome. However, I get the aforementioned errors in Safari and Firefox, respectively. Wondering why this is happening in these browsers and how to fix.
I have spent about 10 hrs doing research on this. Things I tried that made no difference:
I tried adding CORS to my express backend
I tried serving the graphql endpoint as HTTPS
Moving app.use(express.static) in main app.js server file
I couldn't find many other things to try. Everywhere I looked seemed to say that CORS fixed the problem, but mine persists.
Github link: https://github.com/LucaProvencal/thedrumroom
Live Heroku App: https://powerful-shore-83650.herokuapp.com/
App.js (express backend):
const cors = require('cors')
// const fs = require('fs')
// const https = require('https')
// const http = require('http')
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(cors('*')); //NEXT TRY app.use(cors('/login')) etc...
app.use(cors('/*'));
app.use(cors('/'));
app.use(cors('/register'));
app.use(cors('/login'));
app.get('/login', (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
app.get('/register', (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
server.applyMiddleware({ app }); // app is from the existing express app. allows apollo server to run on same listen command as app
const portVar = (process.env.PORT || 3001) // portVar cuz idk if it will screw with down low here im tired of dis
models.sequelize.sync(/*{ force: true }*/).then(() => { // syncs sequelize models to postgres, then since async call starts the server after
app.listen({ port: portVar }, () =>
console.log(`🚀 ApolloServer ready at http://localhost:3001${server.graphqlPath}`)
)
app.on('error', onError);
app.on('listening', onListening);
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Full file is on Github, I tried to post only relevant parts above.
The expected result is that it works in all browsers. It seems from my research that since Heroku serves on HTTPS, Safari and Firefox do not allow requests to HTTP (which is where the graphql server is located, http://localhost:3001/graphql'). When I tried serving Apollo on HTTPS, Heroku just crashed, giving me H13 and 503 errors.
Thanks for any help...
This may also happen during local development when running the front end using HTTPS, but the back end using HTTP.
This is because CORS treats two URLs as having the same origin "only when the scheme, host, and port all match". Matching scheme means matching protocols e.g. both http, or both https.
One solution for local development is to proxy the back end using a tool such as ngrok.
Suppose the front end uses an environment variable which indicates the back end's URL:
BACK_END_API_URL=http://localhost:3005. Then do the following.
Install ngrok
Identify what port the back end is running on e.g. 3005
Run ngrok http 3005 at the command line, which will establish both http and https endpoints. Both will ultimately proxy the requests to the same back end endpoint: http://localhost:3005
After running ngrok it will display the http and https endpoints you can use. Put the one that matches the front end protocol you're using (e.g. https) into your front end environment variable that indicates the back end's URL e.g.
BACK_END_API_URL=https://1234asdf5678ghjk.ngrok.io
Was going to delete this because it is such a silly problem but maybe it will help someone in the future:
I simply replaced all of my 'http://localhost:PORT' endpoints in development with '/graphql'. I assumed that localhost meant local the machine running the code. But an app running on Heroku does not point to localhost. The express server is served on the url (https://powerful-shore-83650.herokuapp.com/) in our case...
At any rate I am so glad I came to a solution. I have a full stack app deployed and connected to a db. Hopefully this post can save someone lots of time.
I am a newer about express with react.Now I have to solve one problem.
Until now I make the server side part by express and client side by react including react router and redux, redux-thunk.When I send the post by axios to the express server then there will be error such below
POST http://localhost:8080/api/users 404 (Not Found)
How can I accept CRUD request by redux-thunk in express?
The server side code is below
//app.js
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '/public')));
app.use('/api/users', userRouter);
app.use('/profile', profileRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
//react redux-thunk side is
axios.post('/api/users', { name: 'LNI' });
You don't have to provide /public instead of just use public.
Path generation is manage by the path module itself.
app.use(express.static(path.join(__dirname, 'public')));
Express POST request is handle like this
app.post('/api/users', userRouter);
Read more about routing from official express documentation - https://expressjs.com/en/guide/routing.html
For reference: https://socket.io/get-started/chat/
The guide says that it's for localhost only:
Socket.IO is composed of two parts:
A server that integrates with (or mounts on) the Node.JS HTTP Server:
socket.io
A client library that loads on the browser side: socket.io-client
During development, socket.io serves the client
automatically for us, as we’ll see, so for now we only have to install
one module.
I've already completed the guide. It works in development. I now want to test this on Heroku (I already know how to deploy to Heroku). The guide seems to be telling me I need socket.io-client to do that, but I'm not sure how to implement it.
Turns out socket.io-client had nothing to do with it. The example wouldn't work on Heroku because process.env.PORT wasn't being used. In index.js replace this:
http.listen(3000, function(){
console.log('listening on *:3000');
});
with this:
http.listen(process.env.PORT || 3000, function(){
console.log('listening on *:3000');
});
Cross site ajax request with Vue.js 1.0 and Vue Resource. I get the following error: XMLHttpRequest cannot load http://dev.markitondemand.com/MODApis/Api/v2/Lookup/jsonp?input=NFLX&callback=handleResponse. No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have a basic understanding of the problem but not sure how to add a callback function with the request or if that is the best solution for this example. I put in the full request URL here just to make it easier to follow.
new Vue({
el: '#stockList',
data: function() {
return {
query: '',
stocks: []
};
},
ready: function() {
this.getStocks();
},
methods: {
getStocks: function() {
this.$http.get('http://dev.markitondemand.com/MODApis/Api/v2/Lookup/jsonp?input=NFLX&callback=handleResponse',
function(data) {
this.stocks = data;
}
);
}
}
})
I have almost zero understanding of networking, but I was able to get several remote apis to work using:
this.$http.jsonp
instead of
this.$http.get
"No Access-Control-Allow-Origin" header usually is a problem with the server. It means that the server is configured to only allow a person access to the API if the request comes from the same domain as the server. You either need to run the script from the website that you are requesting data from, or you need to change the server config to allow access to all domains.
If you don't have access to the server, and you don't want to run the script in the browser, then I think what you could do is use a headless browser like PhantomJS to navigate to the page, insert a script element into the dom that contains you script, execute the function and then return the data from the API. I could write the code out for you, but to be honest, it's a bit complex. You would have to know how to use node.js, and phantom.js. I've personally only used phantom.js for the Node 'html-pdf' package, but I'm sure with a little bit of reading you could figure out how to do it.
Set your local environment to http instead of https if you have no control over dev.markitondemand.com.
I am currently making an Ionic/Cordova-application with Laravel 5 as a Rest-server (my first time coding a PHP-server).
With Postman all my Get/Post/Update/Delete-functions work on Laravel, and on clientside (Ionic Cordova). I am able to send data to http://postcatcher.in using Chrome Allow-Control-Allow-Origin plugin.. Without the plugin, I get this error:
Since this problem apparently only happens in development-mode (when testing client-side in browser), I assume it's alright to develop with the plugin.
When I try to send data to Laravel through Ionic Cordova, I get this error (even with the Allow-Control-Allow-Origin plugin:
I have tried multiple things, such as https://github.com/barryvdh/laravel-cors, which just doesn't seem to work for me. Neither does suggestions in this forum, using CORS-middlewares. https://laracasts.com/discuss/channels/requests/laravel-5-cors-headers-with-filters
I assume that this is a Laravel-issue, but I am not 100% sure.
To publish the server, I use
php artisan serve, giving it localhost:8000.
For the application, I write: ionic serve, which gives it localhost:8100.
At last, this is the code I use to send data on Ionic-side:
.factory('userFactory', function($http, $q) {
return{
createuser : function(info) {
var deferred = $q.defer();
$http.post('localhost:8000/users', info)
.success(function(response, status){
deferred.resolve(response);
})
.error(function() {
console.log('SOMETHING WENT WRONG');
});
return deferred.promise;
}
}
})
Any help is really appreciated. Really stuck with this issue.
So it turns out that I'm an absolute idiot. I just needed to write "http://" in front on the URL. Rookie mistake.
EDIT: I'll keep the question open for just half an hour, in case anyone has advice for me.