下一个js错误-错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头

问题描述 投票:0回答:2

我使用 next.js、Vercel 和 Google Sheets 开发了一个服务器应用程序。我正在使用 Google 表格来保存客户联系数据。我的应用程序逻辑在生产期间在本地运行良好。我在我的谷歌表格中成功接收了数据,没有任何问题。但是,部署后我收到以下错误

error - 错误 [ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头 在新的 NodeError(节点:内部/错误:371:5) 在 ServerResponse.setHeader(节点:_http_outgoing:576:11) 在 ServerResponse._res.setHeader (F:\javascript thiostar ode_modules ext\dist\server ase-server.js:129:24) 在 sendJson (F:\javascript thiostar ode_modules ext\dist\server pi-utils ode.js:195:9) 在 ServerResponse.apiRes.json (F:\javascript thiostar ode_modules ext\dist\server pi-utils ode.js:351:31) 在处理程序 (webpack-internal:///(api)/./pages/api/submit.js:45:21) 在 runMicrotasks() 在 processTicksAndRejections (node:internal/process/task_queues:96:5) 在异步 Object.apiResolver (F:\javascript thiostar ode_modules ext\dist\server pi-utils ode.js:367:9) 在异步 DevServer.runApi (F:\javascript thiostar ode_modules 分机\分布\服务器 ext-server.js:474:9)
在异步 Object.fn (F:\javascript thiostar ode_modules 分机\分布\服务器 ext-server.js:736:37) 在异步 Router.execute (F:\javascript thiostar ode_modules 分机\分布\服务器 外部.js:252:36) 在异步 DevServer.run (F:\javascript thiostar ode_modules ext\dist\server ase-server.js:384:29)
在异步 DevServer.run (F:\javascript thiostar ode_modules 分机\分布\服务器\开发 ext-dev-server.js:732:20) 在异步 DevServer.handleRequest (F:\javascript thiostar ode_modules ext\dist\server ase-server.js:322:20) { 代码:'ERR_HTTP_HEADERS_SENT', 页面:'/api/提交' }

这是我在下一个 js 中的反馈组件:

'use client';

import { useState } from 'react';
import { useForm } from 'react-hook-form';

export default function Feedback() {
  const { register, handleSubmit, reset } = useForm();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [alertMessage, setAlertMessage] = useState('');

  async function submitHandler(data) {
    setLoading(true);
    setError('');
    try {
      const res = await fetch('/api/submit', {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
          'Content-Type': 'application/json',
        },
      });
      if (res.ok) {
        setAlertMessage('message sent successfully');
        reset();
      } else {
        setError('Failed to submit form.');
      }
    } catch (e) {
      console.error(e);
      setError('Failed to submit form.');
    } finally {
      setLoading(false);
    }
  }
  return (
    <div className="container px-6 py-12 mx-auto">
      <div className="lg:flex lg:items-center lg:-mx-6">
        <div className="lg:w-1/2 lg:mx-6">

          <h1 className="text-2xl font-semibold capitalize text-white lg:text-3xl">
            Contact us for <br /> more info
          </h1>
          <div className="mt-6 space-y-8 md:mt-8">
            <p className="flex items-start -mx-2">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="w-6 h-6 mx-2 text-blue-400 "
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
                />
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"
                />
              </svg>
              <span className="mx-2 text-gray-400 truncate w-72 ">
                Cecilia Chapman 711-2880 Nulla St. Mankato Mississippi 96522
              </span>
            </p>
            <p className="flex items-start -mx-2">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="w-6 h-6 mx-2 text-blue-400"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
                />
              </svg>
              <span className="mx-2  truncate w-72 text-gray-400">
                (257) 563-7401
              </span>
            </p>
            <p className="flex items-start -mx-2">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="w-6 h-6 mx-2 text-blue-400"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
                />
              </svg>
              <span className="mx-2 truncate w-72 text-gray-400">
                [email protected]
              </span>
            </p>
          </div>
          <div className="mt-6 w-80 md:mt-8">
            <h3 className="text-gray-300 ">Follow us</h3>
            <div className="flex mt-4 -mx-1.5 ">
              <a
                className="mx-1.5 transition-colors duration-300 transform hover:text-blue-500"
                href="#"
              >
                <svg
                  className="w-10 h-10 fill-current"
                  viewBox="0 0 24 24"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path d="M18.6668 6.67334C18.0002 7.00001 17.3468 7.13268 16.6668 7.33334C15.9195 6.49001 14.8115 6.44334 13.7468 6.84201C12.6822 7.24068 11.9848 8.21534 12.0002 9.33334V10C9.83683 10.0553 7.91016 9.07001 6.66683 7.33334C6.66683 7.33334 3.87883 12.2887 9.3335 14.6667C8.0855 15.498 6.84083 16.0587 5.3335 16C7.53883 17.202 9.94216 17.6153 12.0228 17.0113C14.4095 16.318 16.3708 14.5293 17.1235 11.85C17.348 11.0351 17.4595 10.1932 17.4548 9.34801C17.4535 9.18201 18.4615 7.50001 18.6668 6.67268V6.67334Z" />
                </svg>
              </a>
              <a
                className="mx-1.5 hover:text-blue-400 text-gray-400 transition-colors duration-300 transform"
                href="#"
              >
                <svg
                  className="w-8 h-8"
                  viewBox="0 0 24 24"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M15.2 8.80005C16.4731 8.80005 17.694 9.30576 18.5941 10.2059C19.4943 11.1061 20 12.327 20 13.6V19.2H16.8V13.6C16.8 13.1757 16.6315 12.7687 16.3314 12.4687C16.0313 12.1686 15.6244 12 15.2 12C14.7757 12 14.3687 12.1686 14.0687 12.4687C13.7686 12.7687 13.6 13.1757 13.6 13.6V19.2H10.4V13.6C10.4 12.327 10.9057 11.1061 11.8059 10.2059C12.7061 9.30576 13.927 8.80005 15.2 8.80005Z"
                    fill="currentColor"
                  />
                  <path
                    d="M7.2 9.6001H4V19.2001H7.2V9.6001Z"
                    fill="currentColor"
                  />
                  <path
                    d="M5.6 7.2C6.48366 7.2 7.2 6.48366 7.2 5.6C7.2 4.71634 6.48366 4 5.6 4C4.71634 4 4 4.71634 4 5.6C4 6.48366 4.71634 7.2 5.6 7.2Z"
                    fill="currentColor"
                  />
                </svg>
              </a>
              <a
                className="mx-1.5 hover:text-blue-400 text-gray-400 transition-colors duration-300 transform"
                href="#"
              >
                <svg
                  className="w-8 h-8"
                  viewBox="0 0 24 24"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M7 10.2222V13.7778H9.66667V20H13.2222V13.7778H15.8889L16.7778 10.2222H13.2222V8.44444C13.2222 8.2087 13.3159 7.9826 13.4826 7.81591C13.6493 7.64921 13.8754 7.55556 14.1111 7.55556H16.7778V4H14.1111C12.9324 4 11.8019 4.46825 10.9684 5.30175C10.1349 6.13524 9.66667 7.2657 9.66667 8.44444V10.2222H7Z"
                    fill="currentColor"
                  />
                </svg>
              </a>
              <a
                className="mx-1.5 hover:text-blue-400 text-gray-400 transition-colors duration-300 transform"
                href="#"
              >
                <svg
                  className="w-8 h-8"
                  viewBox="0 0 24 24"
                  fill="none"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M11.9294 7.72275C9.65868 7.72275 7.82715 9.55428 7.82715 11.825C7.82715 14.0956 9.65868 15.9271 11.9294 15.9271C14.2 15.9271 16.0316 14.0956 16.0316 11.825C16.0316 9.55428 14.2 7.72275 11.9294 7.72275ZM11.9294 14.4919C10.462 14.4919 9.26239 13.2959 9.26239 11.825C9.26239 10.354 10.4584 9.15799 11.9294 9.15799C13.4003 9.15799 14.5963 10.354 14.5963 11.825C14.5963 13.2959 13.3967 14.4919 11.9294 14.4919ZM17.1562 7.55495C17.1562 8.08692 16.7277 8.51178 16.1994 8.51178C15.6674 8.51178 15.2425 8.08335 15.2425 7.55495C15.2425 7.02656 15.671 6.59813 16.1994 6.59813C16.7277 6.59813 17.1562 7.02656 17.1562 7.55495ZM19.8731 8.52606C19.8124 7.24434 19.5197 6.10901 18.5807 5.17361C17.6453 4.23821 16.51 3.94545 15.2282 3.88118C13.9073 3.80621 9.94787 3.80621 8.62689 3.88118C7.34874 3.94188 6.21341 4.23464 5.27444 5.17004C4.33547 6.10544 4.04628 7.24077 3.98201 8.52249C3.90704 9.84347 3.90704 13.8029 3.98201 15.1238C4.04271 16.4056 4.33547 17.5409 5.27444 18.4763C6.21341 19.4117 7.34517 19.7045 8.62689 19.7687C9.94787 19.8437 13.9073 19.8437 15.2282 19.7687C16.51 19.708 17.6453 19.4153 18.5807 18.4763C19.5161 17.5409 19.8089 16.4056 19.8731 15.1238C19.9481 13.8029 19.9481 9.84704 19.8731 8.52606ZM18.1665 16.5412C17.8881 17.241 17.349 17.7801 16.6456 18.0621C15.5924 18.4799 13.0932 18.3835 11.9294 18.3835C10.7655 18.3835 8.26272 18.4763 7.21307 18.0621C6.51331 17.7837 5.9742 17.2446 5.69215 16.5412C5.27444 15.488 5.37083 12.9888 5.37083 11.825C5.37083 10.6611 5.27801 8.15832 5.69215 7.10867C5.97063 6.40891 6.50974 5.8698 7.21307 5.58775C8.26629 5.17004 10.7655 5.26643 11.9294 5.26643C13.0932 5.26643 15.596 5.17361 16.6456 5.58775C17.3454 5.86623 17.8845 6.40534 18.1665 7.10867C18.5843 8.16189 18.4879 10.6611 18.4879 11.825C18.4879 12.9888 18.5843 15.4916 18.1665 16.5412Z"
                    fill="currentColor"
                  />
                </svg>
              </a>
            </div>
          </div>
        </div>
        <div className="mt-8 lg:w-1/2 lg:mx-6">

          <div className="w-full px-8 py-10 mx-auto overflow-hidden rounded-lg shadow-2xl bg-[#B3FF17] lg:max-w-xl shadow-black/50">
            {alertMessage && (

            <div className="flex bg-green-lighter max-w-sm mb-4">
              <div className="w-16 bg-green">
                <div className="p-4">
                  <svg className="h-8 w-8 text-white fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M468.907 214.604c-11.423 0-20.682 9.26-20.682 20.682v20.831c-.031 54.338-21.221 105.412-59.666 143.812-38.417 38.372-89.467 59.5-143.761 59.5h-.12C132.506 459.365 41.3 368.056 41.364 255.883c.031-54.337 21.221-105.411 59.667-143.813 38.417-38.372 89.468-59.5 143.761-59.5h.12c28.672.016 56.49 5.942 82.68 17.611 10.436 4.65 22.659-.041 27.309-10.474 4.648-10.433-.04-22.659-10.474-27.309-31.516-14.043-64.989-21.173-99.492-21.192h-.144c-65.329 0-126.767 25.428-172.993 71.6C25.536 129.014.038 190.473 0 255.861c-.037 65.386 25.389 126.874 71.599 173.136 46.21 46.262 107.668 71.76 173.055 71.798h.144c65.329 0 126.767-25.427 172.993-71.6 46.262-46.209 71.76-107.668 71.798-173.066v-20.842c0-11.423-9.259-20.683-20.682-20.683z" /><path d="M505.942 39.803c-8.077-8.076-21.172-8.076-29.249 0L244.794 271.701l-52.609-52.609c-8.076-8.077-21.172-8.077-29.248 0-8.077 8.077-8.077 21.172 0 29.249l67.234 67.234a20.616 20.616 0 0 0 14.625 6.058 20.618 20.618 0 0 0 14.625-6.058L505.942 69.052c8.077-8.077 8.077-21.172 0-29.249z" /></svg>
                </div>
              </div>
              <div className="w-auto text-grey-darker items-center p-4">
                <span className="text-lg font-bold pb-4">
                  Thank you!
                </span>
                <p className="leading-tight">
                  {alertMessage}
                </p>
              </div>
            </div>

            )}
            <h1 className="text-lg font-medium text-gray-900">
              Contact Form
            </h1>
            <form
              onSubmit={handleSubmit(submitHandler)}
              className="mt-6"
              action="/api/submit"
              method="POST"
            >
              <div className="flex-1">
                <label className="block mb-2 text-sm  text-gray-900">
                  Full Name
                </label>
                <input
                  type="text"
                  name="name"
                  placeholder="Your Name"
                  autoComplete="off"
                  {...register('Name', { required: 'Please Enter Name' })}
                  className="block w-full px-5 py-3 mt-2 text-gray-700 placeholder-gray-400 bg-white border border-gray-200 rounded-md dark:placeholder-gray-600 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700 focus:border-blue-400 dark:focus:border-blue-400 focus:ring-blue-400 focus:outline-none focus:ring focus:ring-opacity-40"
                />
                {error && <p className="text-red">{error}</p>}
              </div>
              <div className="flex-1 mt-6">
                <label className="block mb-2 text-sm text-gray-900">
                  Email address
                </label>
                <input
                  type="email"
                  name="email"
                  placeholder="Email"
                  autoComplete="off"
                  {...register('Email', { required: 'Please enter valid email' })}
                  className="block w-full px-5 py-3 mt-2 text-gray-700 placeholder-gray-400 bg-white border border-gray-200 rounded-md dark:placeholder-gray-600 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700 focus:border-blue-400 dark:focus:border-blue-400 focus:ring-blue-400 focus:outline-none focus:ring focus:ring-opacity-40"
                />
                {error && <p className="text-red">{error}</p>}
              </div>
              <div className="w-full mt-6">
                <label className="block mb-2 text-sm text-gray-900">
                  Message
                </label>
                <textarea
                  className="block w-full h-32 px-5 py-3 mt-2 text-gray-700 placeholder-gray-400 bg-white border border-gray-200 rounded-md md:h-48 dark:placeholder-gray-600 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700 focus:border-blue-400 dark:focus:border-blue-400 focus:ring-blue-400 focus:outline-none focus:ring focus:ring-opacity-40"
                  name="message"
                  placeholder="Message"
                  autoComplete="off"
                  {...register('Message', { required: 'Please enter message details' })}
                />
                {error && <p className="text-red">{error}</p>}
              </div>
              <button type="submit" disabled={loading} className="w-full px-6 py-3 mt-6 text-sm font-medium tracking-wide text-white capitalize transition-colors duration-300 transform bg-skin-button-accent hover:bg-skin-button-accent-hover rounded-md focus:outline-none focus:ring focus:ring-blue-300 focus:ring-opacity-50">
                Send Message
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}

这是我的 submit.js 逻辑:

import { google } from 'googleapis';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { Name, Email, Message } = req.body;
    console.log(Name, Email, Message);

    const auth = new google.auth.GoogleAuth({
      credentials: {
        client_email: process.env.GOOGLE_CLIENT_EMAIL,
        private_key: process.env.GOOGLE_PRIVATE_KEY?.replace(/\\n/g, '\n'),
      },
      scopes: [
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/drive.file',
        'https://www.googleapis.com/auth/spreadsheets',

      ],
    });

    const sheets = google.sheets({
      auth,
      version: 'v4',
    });

    const response = await sheets.spreadsheets.values.append({
      spreadsheetId: process.env.GOOGLE_SHEET_ID,
      range: 'A1:C1',
      valueInputOption: 'USER_ENTERED',
      requestBody: {
        values: [[Name, Email, Message]],
      },
    });

    res.status(201).json({ message: 'Date entered successfully' });
  }

  res.status(200).json({ message: 'Done!' });
}

谁能帮我解决这个问题?我试过聊天 GPT 但它不起作用。

javascript google-sheets vercel react-hook-form next
2个回答
1
投票

而不是做 res.status(...) 尝试做 return res.status(....); 您正在尝试发送两次响应,因此出现此错误。但是在您的代码中,您可以在 else 块中添加第二个 res.status(...) ,这将修复它甚至不必返回。

编辑:编辑res.send到res.status


0
投票

我已经解决了这个问题,我只是修改了 submit.js 文件如下:

/* eslint-disable no-unused-vars */

import { google } from 'googleapis';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { Name, Email, Message } = req.body;
    console.log(Name, Email, Message);

    const auth = new google.auth.GoogleAuth({
      credentials: {
        client_email: process.env.GOOGLE_CLIENT_EMAIL,
        private_key: process.env.GOOGLE_PRIVATE_KEY?.replace(/\\n/g, '\n'),
      },
      scopes: [
        'https://www.googleapis.com/auth/drive',
        'https://www.googleapis.com/auth/drive.file',
        'https://www.googleapis.com/auth/spreadsheets',

      ],
    });

    const sheets = google.sheets({
      version: 'v4',
      auth,
    });

    const response = await sheets.spreadsheets.values.append({
      spreadsheetId: process.env.GOOGLE_SHEET_ID,
      range: 'A1:C1',
      valueInputOption: 'USER_ENTERED',
      resource: {
        values: [[Name, Email, Message]],
      },
    });

    res.status(201).json({ message: 'Data entered successfully' });
  } else {
    res.status(200).json({ message: 'Done!' });
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.