basheps
basheps

Reputation: 10624

Web Server send data along with file

I'd like to serve an html page as well as some json to the client without a round-trip that can be processed on the client side. Is this possible? What's the best way of doing this? I've considered sending it in the header but it seems to be frowned upon by some. Any examples are greatly appreciated. Psuedo code:

main(){
  ...
  app.addRequestHandler((req) => req.path == '/user', handler);
}

void handler(req, res) {
  var file = new File(myHtmlFile);
  res.headers.set(...); //add json here?
  res.outputstream...   //or here?
  ...
  stream.pipe(res.outputStream);
}

Upvotes: 1

Views: 174

Answers (1)

Alexandre Ardhuin
Alexandre Ardhuin

Reputation: 76333

In your html file you can put a tag to be replace before sending as response.

For instance, in your html file :

<!DOCTYPE html>
<html>
<head>
  <title>Test</title>
</head>
<body>
  <input type='hidden' id='datas' value="___JSON_DATAS___"/>
  ...
</body>
</html>

___JSON_DATAS___ will be replace in your server with something like :

void handler(req, res) {
  var file = new File(myHtmlFile);
  readStreamAsString(file.openInputStream()).then((fileContent) {
    final content = fileContent
        .replaceAll("___JSON_DATAS___", htmlEscape(jsonAsString));
    res.outputStream.writeAsString(content);
    res.outputStream.close();
  });
}

String htmlEscape(String text) {
  return text.replaceAll("&", "&amp;")
      .replaceAll("<", "&lt;")
      .replaceAll(">", "&gt;")
      .replaceAll('"', "&quot;")
      .replaceAll("'", "&apos;");
}

Future<String> readStreamAsString(InputStream stream) {
  final completer = new Completer();
  final sb = new StringBuffer();
  final sis = new StringInputStream(stream);
  sis
    ..onData = () { sb.add(sis.read()); }
    ..onClosed = () { completer.complete(sb.toString()); }
    ..onError = (e) { completer.completeException(e); };
  return completer.future;
}

Then, on client side :

import 'dart:html';
import 'dart:json';

main(){
  final input = query('#datas') as InputElement;
  final datas = JSON.parse(input.value);
  //...
}

Upvotes: 2

Related Questions