Я получаю сообщение об ошибке: «Не удается установить заголовки после их отправки», и сообщение об ошибке в электронном письме продолжает появляться независимо от того, что находится в файле node.js. - PullRequest
0 голосов
/ 16 мая 2018

каталог выглядит следующим образом: родительская папка «Contact-form» имеет подкаталог «src», который содержит файлы «server.js» и «rout.js», а также содержит другую папку «views», которая имеетфайлы 'contact.ejs' и 'index.ejs'.

это код на 'server.js';

const path = require('path');
const express = require('express');
const layout = require('express-layout');
const bodyParser = require('body-parser');
const validator = require('express-validator');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const flash = require('express-flash');

const routes = require('./routes');
const app = express();

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

const middlewares = [
  validator(),
  layout(),
  express.static(path.join(__dirname, 'public')),
  bodyParser.urlencoded(),
  cookieParser(),
  session({
    secret: 'super-secret-key',
    key: 'super-secret-cookie',
    resave: false,
    saveUninitialized: false,
    cookie: {maxage: 6000}
 }),
 flash()
]

app.use(middlewares);

app.use('/', routes);

app.use((req, res, next) => {
  res.status(404).send("Sorry can't find that!")
});

app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
});

app.listen(3000, () => {
  console.log(`App running at http://localhost:3000`)
});

, затем на 'rout.js';

 const express = require('express');
 const router = express.Router();
 const { check, validationResult } = require('express-validator/check');
 const { matchedData } = require('express-validator/filter');

 router.get('/', (req, res) => {
   res.render('index')
 });

 router.get('/contact', (req,res) => {
   res.render('contact', {
   data: {},
   errors: {}
  });
 });

 router.post('/contact', [
 //validation using 'express-validaor' && 'express-validator/check' and 
 //Sanitization using
 // 'express-validator/filter'
   check('message')
    .isLength({ min:1 })
    .withMessage('Message is required')
    .trim(),
   check('email')
    .isEmail().withMessage('That Email doesn\'t look right')
    .trim()
    .normalizeEmail()
  ], (req,res) => {
  const errors = validationResult(req);
  res.render('contact', {
    data: req.body,
    errors: errors.mapped()
   });

   const data = matchedData(req);
   console.log('Sanitized: ', data);

  //Sending sanitized data and redirecting to the index page
   req.flash('success', 'Thanks for the message! I\'ll be in touch :) ');
   res.redirect('/');
 });
 module.exports = router;

на 'contact.ejs';

<div class="form-header">
   <% if(Object.keys(errors).length === 0) { %>
    <h2>Send us a Message</h2>
   <% } else { %>
      <h2 class="error-heading">Oops, please correct the following:</h2>
      <ul class="erroe-list">
          <% Object.values(errors).forEach(error => { %>
              <li> <%= error.msg %> </li>
       <%  }) %>
      </ul>
   <% } %>
</div>
<form method="POST" action="/contact" novalidate>
  <div class="form-field <%= errors.message ? 'form-field-invalid' : '' %>">
      <label for="message">Message</label>
       <textarea class="input" id="message" name="message" rows="4" 
      autofocus >
      <%= data.message %> </textarea>
      <% if (errors.message) { %>
          <div class="error"><%= errors.message.msg %></div>
       <% } %>
   </div>
   <div class="form-field <%= errors.email ? 'form-field-invalid' : '' %>">
      <label for="email">Email</label>
      <input class="input" id="email" type="email" value="<%= data.email %>" 
   />
     <% if (errors.email) { %>
          <div class="error"><%= errors.email.msg %></div>
     <% } %>
   </div>
   <div class="form-actions">
      <button class="btn" type="submit" >Send</button>
   </div>
</form>

и на 'index.ejs'

 <h1>Working With Forms in Node.js</h1>

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

В router.post ('/ contact') у вас есть render (), за которым следует redirect () ниже, это приведет к ошибке.

0 голосов
/ 16 мая 2018

Can't send headers after they are sent - универсальное сообщение для: Вы уже отправили ответ . Вы одновременно визуализируете страницу и перенаправляете, что не имеет никакого смысла.

Так что либо:

res.render('contact', {
    data: req.body,
    errors: errors.mapped()
 });

Или

const data = matchedData(req);
console.log('Sanitized: ', data);

//Sending sanitized data and redirecting to the index page
req.flash('success', 'Thanks for the message! I\'ll be in touch :) ');
res.redirect('/');

Если вы хотите только render в случае ошибки и redirect в случае успеха, сделайте следующее:

const errors = validationResult(req);

if (!errors.isEmpty()) {
    // Notice the return, so redirect won't run.
    return res.render('contact', {
        data: req.body,
        errors: errors.mapped()
    });
}

const data = matchedData(req);
console.log('Sanitized: ', data);

//Sending sanitized data and redirecting to the index page
req.flash('success', 'Thanks for the message! I\'ll be in touch :) ');
res.redirect('/');

А что касается ошибки электронной почты, вам не хватает атрибута name в электронной почте input, без него ничего не будет опубликовано.

<input class="input" name="email" id="email" type="email" value="<%= data.email %>" 
   />

Для получения дополнительной информации посмотрите следующий вопрос: Ошибка: невозможно установить заголовки после их отправки клиенту

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...