I have created two Flutter applications. The first is Android app and contains an HTTP server that I want to use to serve this application via a web page. The second is Flutter web application. I built the second application and thanks to that I got files like index.html, main.dart.js and others. I would like to add these files to the first application so that when the HTTP server is turned on and the correct web page is loaded with the appropriate IP and port, this second application will be displayed. Is this possible? I have added these files to the assets folder, I have also added them to pubspec.yaml. I created a function that reads the index.html and sends it to the client using request.response.write.
Future<void> showWeb(HttpRequest request) async {
String _content = await rootBundle.loadString('assets/files/web/index.html');
request.response
..statusCode = HttpStatus.ok
..headers.set("Content-Type", "application/javascript; charset=utf-8")
..write(_content)
..close();
}
I put "text/html" as the header, which throws me an error "content type mismatch". When I add "application/javascript" as a header, I get the source code of the html file.
Is it possible to view the Flutter web app using an HTTP server?
After some time I came back to this project and came up with a solution to my problem. Maybe it will help someone.
- assets/web/
- assets/web/assets/
- assets/web/assets/fonts/
- assets/web/assets/packages/cupertino_icons/assets/
- assets/web/assets/shaders/
- assets/web/canvaskit/
- assets/web/canvaskit/profiling/
- assets/web/icons/
void handleGet(HttpRequest request) async {
final path = request.uri.path;
String _content;
Uint8List _contentByte;
String _mimeType;
bool isItByte;
try {
isItByte = false;
if (path == '/') {
_content = await rootBundle.loadString('assets/web/index.html');
_mimeType = 'text/html; charset=utf-8';
} else {
var dotoffset = path.lastIndexOf('.');
if (path.substring(dotoffset) == '.png' ||
path.substring(dotoffset) == '.ttf' ||
path.substring(dotoffset) == '.otf') {
_contentByte = await File('assets/web' + path.toString()).readAsBytes();
isItByte = true;
} else {
_content = await rootBundle.loadString('assets/web' + path.toString());
}
_mimeType = dotoffset == -1
? 'text/plain; charset=utf-8'
: {
'.html': 'text/html; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.js': 'text/javascript; charset=utf-8',
'.csv': 'text/csv; charset=utf-8',
'.txt': 'text/plain; charset=utf-8',
'.ico': 'image/x-icon',
'.jpg': 'image/jpg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.json': 'application/json',
'.xml': 'application/xml',
'.ttf': 'font/ttf',
'.otf': 'font/otf'
}[path.substring(dotoffset)];
}
if (isItByte) {
request.response
..statusCode = HttpStatus.ok
..headers.set("Content-Type", _mimeType)
..write(_contentByte)
..close();
} else {
request.response
..statusCode = HttpStatus.ok
..headers.set("Content-Type", _mimeType)
..write(_content)
..close();
}
} catch (e) {
print(e.toString());
}
}
It is necessary that both applications have the same font and then everything works.
The code is not optimized, I'm still working on it, but it's enough for an illustration.