我正在学习飞镖并创建了一个简单的联系表格 - 基于飞镖网站上的表格教程,使用邮件发送邮件。
到目前为止一切顺利 - 客户发布消息,服务器获取发布数据,创建信封并发送邮件......但我想向填写表单的人显示一条令人欣慰的消息,或者发出警告如果没有发送它们。
问题是http响应是在发送电子邮件的未来发送之前发送的 -
Chris Storm谈到使用完成者来解决这个问题,我想 - 在这里:testing error conditions with dart再一次在Dart for Hipsters的一章中,但我发现很难弄清楚如何在这里应用它。这是完整的服务器代码 - sendMail函数中的注释显示问题。
import 'dart:io';
import 'dart:convert';
import 'package:mailer/mailer.dart';
final HOST = '127.0.0.1'; // eg: localhost
final PORT = 4040; // a port, must match the client program
void main() {
HttpServer.bind(HOST, PORT).then(gotMessage, onError: printError);
}
void gotMessage(_server) {
_server.listen((HttpRequest request) {
switch (request.method) {
case 'POST':
handlePost(request);
break;
case 'OPTIONS':
handleOptions(request);
break;
default: defaultHandler(request);
}
},
onError: printError); // .listen failed
print('Listening for GET and POST on http://$HOST:$PORT');
}
/**
* Handle POST requests
*
*/
void handlePost(HttpRequest req) {
HttpResponse res = req.response;
print('${req.method}: ${req.uri.path}');
addCorsHeaders(res);
req.listen((List<int> buffer) {
// Create a new string from the characters in the buffer and convert this into a map
Map postData = JSON.decode(new String.fromCharCodes(buffer));
res.write(sendMail(postData));
res.close();
},
onError: printError);
}
/**
* Add Cross-site headers to enable accessing this server from pages
* not served by this server
*
* See: http://www.html5rocks.com/en/tutorials/cors/
* and http://enable-cors.org/server.html
*/
void addCorsHeaders(HttpResponse res) {
res.headers.add('Access-Control-Allow-Origin', '*, ');
res.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.headers.add('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
}
void handleOptions(HttpRequest req) {
HttpResponse res = req.response;
addCorsHeaders(res);
print('${req.method}: ${req.uri.path}');
res.statusCode = HttpStatus.NO_CONTENT;
res.close();
}
void defaultHandler(HttpRequest req) {
HttpResponse res = req.response;
addCorsHeaders(res);
res.statusCode = HttpStatus.NOT_FOUND;
res.write('Not found: ${req.method}, ${req.uri.path}');
res.close();
}
void printError(error) => print(error);
sendMail(postData) {
String sentMsg = 'I am waiting for a result to report'; //initialised value
var options = new GmailSmtpOptions()
..username = 'my.mailt@gmail.com' //shove real values in here to test
..password = 'my_password';
var transport = new SmtpTransport(options);
// Create the envelope to send.
var envelope = new Envelope()
..fromName = postData['name']
..from = postData['fromEmail']
..recipients = ['the_recipient@somedomain.com']
..subject = 'Message from contact form'
..text = postData['contactMessage'];
transport.send(envelope)
.then((success) => sentMsg = 'Message sent, thank you.' ) //this will not be returned...
.catchError((e) => sentMsg = 'Message not sent; the reported error was: $e'); // nor will this
return sentMsg; // Sadly the initial value will be returned as the future (transport.send) will not have completed
}
答案 0 :(得分:0)
您的代码看起来不错:)
据我所知,并没有多少遗漏(尽管没有尝试过执行)。
request.response.write('Hello, world');
request.response.close();
位于handlePost()
(您可以req
可用的地方)
返回您要从handlePost()
返回到gotMessage()
的客户端的结果,并在其中添加以上行。
另请查看An Introduction to the dart:io Library - Writing web servers
答案 1 :(得分:0)
如果我做对了,你想根据transport.send()
的结果发送回复。如果是这样,你可以返回它,比如
return transport.send(envelope)
.then((success) => sentMsg = 'Message sent, thank you.' )
.catchError((e) => sentMsg = 'Message not sent; the reported error was: $e');
或使用Completer
var c = new Completer();
transport.send(envelope)
.then((success) => sentMsg = 'Message sent, thank you.' )
.then(c.complete)
.catchError((e) => sentMsg = 'Message not sent; the reported error was: $e');
return c.future;
由于您要返回Future
,您必须更改向客户发送回复的方式,
res.write(sendMail(postData));
res.close();
到
sendMail(postData)
.then((result) {
res.write(result);
res.close();
});