flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
165.59k stars 27.34k forks source link

[web]: Support for backend proxy #51530

Open devcsrj opened 4 years ago

devcsrj commented 4 years ago

On the traditional web frameworks such as Angular, React, and Vue, they tend to provide a way to automatically proxy requests to the backend. For instance, in Angular, simply providing a proxy.conf.json does the trick. All 3 seem to achieve this using an express server with a proxy middleware.

As of the moment, the flutter docs seem to hint that the only way is to allow CORS on the server-side. While this is doable, it still is not as pretty as it requires you to put a CORS-during-dev condition on the server.

Is this feature on the roadmap for the stable release?

$ flutter --version
Flutter 1.14.6 • channel beta • https://github.com/flutter/flutter
Framework • revision fabeb2a16f (4 weeks ago) • 2020-01-28 07:56:51 -0800
Engine • revision c4229bfbba
Tools • Dart 2.8.0 (build 2.8.0-dev.5.0 fc3af737c7)

P.S.: I'm also interested in contributing to flutter, so if the team sees this fit to be prioritized, please guide me accordingly!

jonahwilliams commented 4 years ago

Hi @devcsrj - there are no plans to implement this feature anytime soon, but I would certainly review a patch that added this functionality to the flutter tool.

I would consider introducing this as a flag to flutter run, perhaps --web-proxy-server ? (Taking other suggestions for names). This would live alongside the other web specific flags in the tool, like --web-hostname: https://github.com/flutter/flutter/blob/b34046903b527ed401ff84c23651680593bea86f/packages/flutter_tools/lib/src/commands/run.dart#L348

The second change would be to update the development server (https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/build_runner/devfs_web.dart#L53) to consume this option and perform the proxying of requests.

devcsrj commented 4 years ago

I would consider introducing this as a flag to flutter run, perhaps --web-proxy-server

Sounds good to me!

Another thing to consider though - the npm-based middleware is flexible, as it supports proxying only certain paths, path rewrites, web sockets (and SSE, I think). While a command-line flag is enough for my use case as of the moment, I'm not exactly sure how many users require the above flexibility. Might get unwieldy (or become too limiting) when implemented as a flag.

Just additional notes to consider!

toplinuxsir commented 3 years ago

If the function is dead ,To debug web app is just a JOKE!

toplinuxsir commented 3 years ago

The designers of flutter without any experience of web devleopment ,The function is very important for debug web app

larbjo commented 3 years ago

Anything new about this case? I am really looking forward to get a backend proxy for web.

elisherer commented 3 years ago

I was able to serve both my flutter web app and another server on the same port using a proxy server in nodejs.

proxy.js

const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");

const EXT_PORT = 801;

const app = express();

app.use(
  createProxyMiddleware({
    changeOrigin: true,
    target: "http://localhost:8000", // shouldn't matter
    router: {
      [`localhost:${EXT_PORT}/api`]: "http://localhost:8081", // API on 8081 should support /api/* paths
      [`localhost:${EXT_PORT}`]: "http://127.0.0.1:8082" // everything else will be proxied to flutter on 8082
    }
  })
);

app.listen(EXT_PORT, () => {
  console.log(
    "Server listening on: " +
      EXT_PORT +
      "\nRun flutter with: flutter run -d chrome --web-port 8082 --web-hostname 127.0.0.1"
  );
});

In this example, open browser on http://localhost:801 Calls to http://localhost:801/api/* will be proxied to the backend

woprandi commented 3 years ago

Any nginx configuration is easier than write yourself a proxy server

Kerolos9008 commented 2 years ago

Any updates about this topic, as it is extremely important for WEB development process to be able to send the cookie with each request to any public URL.

superandrew commented 2 years ago

I noticed that this issue is still open. I am new to flutter web development so I was surprised that there is no easy way to proxy calls made to the backend. The surprise is motivated by the fact that any web developer knows how CORS is problematic to deal with during development, so it sounds strange not so much that a web framework such as flutter 2.0 is is missing this feature but that there is no plan to implement it.

Out of curiosity, is there a way that doesn't involve a flutter-level proxy but instead some configuration (on retrofit, for example)?

My issue with the proxy shared by @elisherer is that I am still having CORS issues because I run flutter on a port and the proxy on another. Is there a better way to do this?

DeanPDX commented 2 years ago

My issue with the proxy shared by @elisherer is that I am still having CORS issues because I run flutter on a port and the proxy on another. Is there a better way to do this?

I don't know if this is helpful at all, but I'm debugging my app using Windows native so the HTTP client doesn't care about CORS. Only other thing I can think of is to create a local proxy that forwards your traffic and responds to OPTIONS with a permissive Access-Control-Allow-Origin header. I haven't tested that yet as I was able to debug using Windows native (and when I deploy my app, the API and web content are coming from same URL so it works). I'm on a tight schedule currently but might try implementing a proxy setup in the future and will check back if I find a good solution.

wytrych commented 2 years ago

I had to write my own little node proxy server using the http-proxy-middleware. A bit wasteful if every team needs to do it themselves.

wytrych commented 2 years ago

@superandrew in this setup you need to go to http://localhost:8000 and the proxy will direct the calls to either flutter running on 8082 and /api to 8081 - the browser should be happy with thiis

mrcndn commented 2 years ago

I am able to proxing on express for frontend, however on dotnet minimal api there is no good solution for this. So if you add proxy functionality to flutter it would be great.

mrcndn commented 2 years ago

Also, the problem with the backend proxy is debugging. Because original flutter app running on another port, hot reload is not working on proxied app.

tecteun commented 2 years ago

I've made a example patch for /packages/flutter_tools/lib/src/isolated/devfs_web.dart which routes all traffic from the devservers /api path to https://example-api-service.com/

see https://gist.github.com/tecteun/82776cf69805ce59d89f56a173af127b:corsproxypatch.patch

Apply the patch using

PATCH=`pwd`/corsproxypatch.patch; (cd `dirname $(which flutter)`/../; git apply $PATCH --verbose); rm `dirname $(which flutter)`/cache/flutter_tools.stamp; flutter precache;

Remove the patch again using

(cd `dirname $(which flutter)`/../; git checkout HEAD --progress -- packages/flutter_tools/lib/src/isolated/devfs_web.dart)

So if you use the /api path in your app for local development, CORS can be circumvented this way.

kevmoo commented 1 year ago

@tecteun – that's an AMAZING work-around.

I really want CLI support for this. Will look into it soon!

tecteun commented 1 year ago

Cool! Yes, would be really nice to have this in the CLI, tried to implement it, but ran into issues trying to run the middleware handler in a deferred isolate, so it could be individually configured for each program in a project local .dart file. (I really don't know what would be the best pattern for local configuration in combination with flutter/dart)

woprandi commented 1 month ago

@tecteun Maybe open a PR for this ?

dominicmh commented 1 week ago

If only CORS is your issue, you can apply the flutter run argument --web-browser-flag=--disable-web-security.