简体   繁体   中英

Proxy error: Could not proxy request /getThing from myapp.herokuapp.com to http://localhost:3001

I have a MERN stack app built using Facebook's Create-React-App template and Nodejs/Express. I am using Heroku's Nodejs Buildpack . I was able to deploy my app to Heroku after "Dangerously Disabling Host Check" .

Reproducible Demo (instructions in readme)

My site displays information, but requests to my back-end don't work (both the server and React run on the same Heroku app). When my site tries to make a request to an endpoint such as /getThing, the browser console displays this:

XML Parsing Error: syntax error
Location: https://myapp.herokuapp.com/getThing
Line Number 1, Column 1:
getThing:1:1
Error: Request failed with status code 500

My Heroku logs gives me this (only relevant portion included):

2018-03-11T04:27:01.058036+00:00 heroku[router]: at=info method=POST path="/getThing" host=myapp.herokuapp.com request_id=e587a6ee-1dbf-4a2d-9caf-07d9478b5a39 fwd="128.84.126.1
26" dyno=web.1 connect=1ms service=32ms status=500 bytes=297 protocol=https
2018-03-11T04:27:01.032269+00:00 heroku[router]: at=info method=GET path="/static/js/bundle.js.map" host=myapp.herokuapp.com request_id=a4fd078d-07f1-4796-b0fe-555f8f389920 fwd="128.84.126.126"
 dyno=web.1 connect=0ms service=7ms status=304 bytes=176 protocol=https
2018-03-11T04:27:01.055673+00:00 app[web.1]: Proxy error: Could not proxy request /getThing from myapp.herokuapp.com to http://localhost:3001/.
2018-03-11T04:27:01.055735+00:00 app[web.1]: See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
2018-03-11T04:27:01.055787+00:00 app[web.1]:
2018-03-11T04:27:02.212247+00:00 heroku[router]: at=info method=GET path="/sockjs-node/info?t=1520742420523" host=myapp.herokuapp.com request_id=91c5363e-dbf3-4d15-9482-b44bc1dc3205 fwd="128.84
.126.126" dyno=web.1 connect=0ms service=3ms status=200 bytes=363 protocol=https

The 4th line is where the error is. I've been using a proxy in my package.json, but I've read Heroku ignores that so it shouldn't be a problem. My package.json is included below.

{
  "name": "myapp",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:3001/",
  "dependencies": {
    "@sendgrid/mail": "^6.2.1",
    "async": "^2.6.0",
    "aws-sdk": "^2.205.0",
    "axios": "^0.14.0",
    "body-parser": "~1.17.1",
    "cookie-parser": "~1.4.3",
    "cors": "^2.8.4",
    "debug": "^2.6.9",
    "dotenv": "^5.0.1",
    "express": "~4.15.2",
    "express-fileupload": "^0.4.0",
    "font-awesome": "^4.7.0",
    "foreman": "^2.0.0",
    "history": "^4.7.2",
    "marked": "^0.3.17",
    "milligram": "^1.3.0",
    "milligram-react": "0.0.0",
    "mongodb": "^2.2.35",
    "mongoose": "^4.13.11",
    "morgan": "~1.8.1",
    "nodemailer": "^4.6.0",
    "nodemon": "^1.17.1",
    "react": "^16.2.0",
    "react-bootstrap": "^0.32.1",
    "react-dom": "^16.2.0",
    "react-fontawesome": "^1.6.1",
    "react-icons": "^2.2.7",
    "react-onclickoutside": "^6.7.1",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.0.17",
    "react-table": "^6.8.0",
    "sendgrid-web": "0.0.5",
    "serve-favicon": "~2.4.2",
    "supports-color": "^5.3.0"
  },
  "engines": { "node": "6.11.3", "npm": "5.7.1"},
  "scripts": {
    "start": "react-scripts start | node server.js",
    "start-dev": "set DEBUG=* & nodemon server.js",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

And here's the server code to start the server:

const port = process.env.PORT || 3001;
app.listen(port, function () {
    debug(`api running on port ${port}`);
});

I'm even allowing cors everywhere:

const cors = require('cors');
app.use(cors());

File structure:

Any ideas would be greatly appreciated. Let me know if you need any additional information.

So you have few issues here.

Heroku runs one web dyno for you automatically, but other process types don't start by default. To launch a worker, you need to scale it up to one dyno:

Which means by default your API dyno is not even up. You need to execute below command to get it up

heroku ps:scale api=1

But then also it won't help because, your API is not http reachable and has web dyno has no way of known where the api is. There is possibility to do that, but I won't go into that solution for this answer

You can find more details on below

https://devcenter.heroku.com/articles/dyno-dns-service-discovery

You might need to change your server.js like below

const host = process.env.HEROKU_PRIVATE_IP || '0.0.0.0';
//starts the server and listens for requests
app.listen(port, host, function () {
    debug(`api running on port ${port}`);
});

and also update package.json to

"proxy": "http://<apidnsname>:3001"

But as I said I would not prefer that solution as it needs to hardcode the dnsname in the package.json .

Actual Fix

  • Delete the Procfile (heroku will automatically run npm start )
  • Add the concurrently package npm add concurrently
  • Change the start script to "start": "concurrently \\"react-scripts start\\" \\"PORT=3001 node server.js\\"" . This does two things. Fixes the PORT for your api server process. And also starts the server in the same dyno, so it can be reached over the same localhost network

Deploy the app and now it works

部署的Heroku应用

Below is a sample working app for you to check, which will be live for sometime and then I will remove it

https://soproxyapp.herokuapp.com/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM