In react, how do I pass backend REST APIs to my frontend?

我的未来我决定 提交于 2019-12-11 21:30:58

问题


Pretty noobish question here, I do not wish to draw flak. I have my frontend created with create-react-app and I'm using fetch to pass in the backend APIs to my frontend. The backend is running on localhost:8080 on the same machine as the frontend. Frontend is running on port 3000. I have hardcoded the URLs as "http://localhost:8080/getForm" and so on. It all works fine if I access the frontend on the same machine as it is hosted. However, if I access the frontend from a different machine, the API calls fail, which would make sense because the calls are being made to localhost.

Now, what would be the best approach to pass in machine-independent rest URLs? I do not want to set a static IP for my backend. I have tried:

  1. Making a production build and bundling it with the backend. This again makes calls to localhost on the accessing machine, which fails.
  2. Manipulating the URL with window.location.hostname+"getForm". This fails when I have different servers hosting frontend and backend.

Edit* Okay, I managed to add a proxy to the node server by adding the following line to package.json. "proxy":"http://localhost:8080/" This forwards something like localhost:3000/api/getForm on the frontend to localhost:8080/api/getForm on the backend. This works pretty well, but now I am stuck on an issue which I presume is due to incorrect CORS setting. Proxied GET requests to the backend, which is a Spring Boot API, work fine, but proxied POST requests return a 403, with the response "Invalid CORS request".

I have added a @CrossOrigin(origins="http://localhost:3000") to the class-level of my spring application which should make all the apis CORS friendly. Also, I am using fetch on the frontend to make calls. Any leads on what I might be getting wrong?

POST /api/post HTTP/1.1 Host: localhost:3000 Connection: keep-alive Content-Length: 22 Origin: http://localhost:3000 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 Content-Type: application/json Accept: / Referer: http://localhost:3000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-IN,en-GB;q=0.9,en-US;q=0.8,en;q=0.7

Body - {"title":"abc","body":"def"}

Response - 403, Invalid CORS request

GET /api/get HTTP/1.1 Host: localhost:3000 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 Accept: / Referer: http://localhost:3000/ Accept-Encoding: gzip, deflate, br Accept-Language: en-IN,en-GB;q=0.9,en-US;q=0.8,en;q=0.7

Response - 200, [{"id":1,"title":"Post 1","body":"Backend is connected fine and dandy!"}]


回答1:


When you dont serve your code using node, you can use webpack to add globals, but then you need to create separate build for each environment.

When using Node with SSR:

What I usually do is use a .env file with specific constants for hostname, port, .. and use those in a js config file. Then you can import that js file and use it for your fetch calls. You can use dotenv (https://www.npmjs.com/package/dotenv) for adding the .env variables to your node process.

config file:

const config = {
  env: {
    host: (envConfig && envConfig.API_HOST) || 'localhost',
    port: (envConfig && envConfig.API_PORT) || '8000',
    httpOrigin: (envConfig && envConfig.API_PROTOCOL) || 'http'
  }
}

export default config;

.env file:

API_PROTOCOL=https
API_HOST=localhost
API_PORT=8000

To transfer the config to the frontend you can seriablize in the the body of your html and pick it up on your client side render.

<script dangerouslySetInnerHTML={{ __html: `window.__envConfig=${serialize(envConfig)};` }} charSet="UTF-8"/>


来源:https://stackoverflow.com/questions/51055817/in-react-how-do-i-pass-backend-rest-apis-to-my-frontend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!