fetch不让Express.js/node.js在客户端中从服务器端到EJS模板的响应

发布于 2025-01-26 10:00:19 字数 5463 浏览 1 评论 0原文

目的:从客户端读取输入(数据),将数据发送到服务器端(node.js/express.js),修改服务器端上的数据并发送修改后的数据返回客户端(EJS模板)

问题:当我将fetch()和用于发布的方法设置时,我可以将数据发送到服务器端,但是我无法渲染修改后的数据数据回到客户端。但是,如果我直接将HTML表格与要发布的方法集中使用,则可以实现目标(目的)。但是,我需要发布fetch()。

研究: 为了缩小问题,尤其是检查服务器端代码,我尝试了以下代码,而无需fetch():我将用户的名称从输入中获取并将其发送到服务器端。在服务器端,我添加一个Hello,然后返回“ Hello first_name last_name!”到一个名为Word的EJS变量:

HTML表单(在EJS模板中):

<form action="/users" id="example-form" method="POST">
    <label for="first-name">
        <strong>First Name:</strong>
        <input type="text" name="first_name" id="first-name">
    </label>

    <label for="last-name">
        Last Name:
        <input type="text" name="last_name" id="last-name">
    </label>

    <input type="submit" value="Create new user">
</form>

<br><hr><br>
<% var word %>
<h2><%= word %></h2>

服务器端代码为:

//app.use(express.json())

app.post('/users', (req,res) => {

    console.log(req.body)
     
    res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })
    
})

我发表了评论

//app.use(express.json())

,并且代码无需它。

现在,我从HTML代码中删除方法=“ post”。以下代码从 Simon Plenderleith的网站

HTML代码:

   <form action="/users" id="example-form">
        <label for="first-name">
            <strong>First Name:</strong>
            <input type="text" name="first_name" id="first-name">
        </label>
    
        <label for="last-name">
            Last Name:
            <input type="text" name="last_name" id="last-name">
        </label>
    
        <input type="submit" value="Create new user">
    </form>

我将以下内容添加到此HTML代码中,然后将它们全部保存在index5.ejs中:

<br><hr><br>
<% var word %>
<h2><%= word %></h2>

我从 simon plenderleith的网站 index5.ejs:

  async function postFormDataAsJson({ url, formData }) {
        const plainFormData = Object.fromEntries(formData.entries());
        const formDataJsonString = JSON.stringify(plainFormData);

        const fetchOptions = {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json",
            },
            body: formDataJsonString,
        };

        const response = await fetch(url, fetchOptions);

        if (!response.ok) {
            const errorMessage = await response.text();
            throw new Error(errorMessage);
        }

        return response.json();
    }


    async function handleFormSubmit(event) {
        event.preventDefault();

        const form = event.currentTarget;
        const url = form.action;

        try {
            const formData = new FormData(form);
            const responseData = await postFormDataAsJson({ url, formData });

            console.log({ responseData });
        } catch (error) {
            console.error(error);
        }
    }

    const exampleForm = document.getElementById("example-form");
    exampleForm.addEventListener("submit", handleFormSubmit);

</script>

这给了这一点 :在控制台(客户端Chrome Dev工具)中以下错误消息:

SyntaxError: Unexpected token < in JSON at position 0

另外,在客户端的控制台中,我们看到我们已经收到了一个空对象:

{}

我们仍然看不到任何Hello hello first_name last_name! (例如,约翰·史密斯(John Smith),您好!)在客户端! 该代码也未能将这些字符串归还到

上述服务器代码中的客户端(index5.ejs),我从app.use(express.json())中删除注释//

因此, 服务器端上的代码:

app.use(express.json())

app.post('/users', (req,res) => {

    console.log(req.body)
     
    res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })
    
})

现在,我们再次尝试约翰·史密斯(John Smith):

这次我们进行了改进,并且在服务器端的控制台中获取了此对象:

{ first_name: 'John', last_name: 'Smith' }

我们看不到Hello John Smith!在客户端上,当我们将fetch()与方法设置的方法使用时,服务器端代码无法将其渲染到EJS变量单词。请记住,当方法=“ post”设置在标签中时,服务器端代码可与HTML表单一起使用。

另外,我仍然在客户端(Chrome dev工具)的控制台中获取此错误消息:

(index):68 SyntaxError: Unexpected token < in JSON at position 0

使用Chrome Dev工具,可以将此错误追溯到上述JavaScript代码中的以下代码行:

 console.error(error);

使用Chrome在网络/fetch/xhr/有效载荷下的开发工具,我看到以下内容:

{first_name: "John", last_name: "Smith"}
first_name: "John"
last_name: "Smith"

似乎上面的fetch()代码成功地将数据发送到服务器端,但是服务器端代码的以下部分失败了:

 res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })

清楚,清楚,清楚,我必须更好地了解客户端和服务器端之间的数据如何来回。当我继续为此努力时,如果您可以帮助我找出我所缺少的内容,并且您建议您快速修复上述代码,我将不胜感激。

最好的问候,

ERIC

更新2022年5月4日

如果我

return response.json()

在JavaScript代码(客户端)中更改为

return response

控制台(客户端端)中的错误消息消失。手头的问题:为什么使用常规表格,node.js/express.js可以渲染到EJS模板,但使用fetch()不能。

Purpose: Reading input (data) from the client-side, sending the data to the server-side (Node.js/Express.js), modifying the data on the server-side, and sending the modified data back to the client-side (EJS template)

Problem: When I use fetch() with the method set to POST, I can send data to the server-side, but I cannot render the modified data back to the client-side. However, if I use the HTML form directly with the method set to POST, I can achieve the goal (the purpose). However, I need to POST with fetch().

Research:
To narrow down the problem and especially check on the server-side code, I tried the following code without fetch(): I take the user's name from the input and send it to the server-side. On the server-side, I add a Hello and then return "Hello first_name last_name!" to an EJS variable named word:

The HTML form (in an ejs template):

<form action="/users" id="example-form" method="POST">
    <label for="first-name">
        <strong>First Name:</strong>
        <input type="text" name="first_name" id="first-name">
    </label>

    <label for="last-name">
        Last Name:
        <input type="text" name="last_name" id="last-name">
    </label>

    <input type="submit" value="Create new user">
</form>

<br><hr><br>
<% var word %>
<h2><%= word %></h2>

The server-side code is:

//app.use(express.json())

app.post('/users', (req,res) => {

    console.log(req.body)
     
    res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })
    
})

I commented out

//app.use(express.json())

and the code works without it.

Now, I remove method = "POST" from the HTML code. The following code is adopted from Simon Plenderleith's website:

HTML code:

   <form action="/users" id="example-form">
        <label for="first-name">
            <strong>First Name:</strong>
            <input type="text" name="first_name" id="first-name">
        </label>
    
        <label for="last-name">
            Last Name:
            <input type="text" name="last_name" id="last-name">
        </label>
    
        <input type="submit" value="Create new user">
    </form>

I add the following to this HTML code and save them all in index5.ejs:

<br><hr><br>
<% var word %>
<h2><%= word %></h2>

I add the following JavaScript code from Simon Plenderleith's website to index5.ejs:

  async function postFormDataAsJson({ url, formData }) {
        const plainFormData = Object.fromEntries(formData.entries());
        const formDataJsonString = JSON.stringify(plainFormData);

        const fetchOptions = {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json",
            },
            body: formDataJsonString,
        };

        const response = await fetch(url, fetchOptions);

        if (!response.ok) {
            const errorMessage = await response.text();
            throw new Error(errorMessage);
        }

        return response.json();
    }


    async function handleFormSubmit(event) {
        event.preventDefault();

        const form = event.currentTarget;
        const url = form.action;

        try {
            const formData = new FormData(form);
            const responseData = await postFormDataAsJson({ url, formData });

            console.log({ responseData });
        } catch (error) {
            console.error(error);
        }
    }

    const exampleForm = document.getElementById("example-form");
    exampleForm.addEventListener("submit", handleFormSubmit);

</script>

This gives the following error message in the console (client-side Chrome dev tool):

SyntaxError: Unexpected token < in JSON at position 0

Also, in the console in the client-side we see we have received an empty object:

{}

We still do not see any Hello first_name last_name! (e.g. Hello John Smith!) on the client-side! So the code also failed to render back those strings to the client-side (index5.ejs)

In the above-given server code, I remove the comment // from app.use(express.json())

So, this is now the code on the server-side:

app.use(express.json())

app.post('/users', (req,res) => {

    console.log(req.body)
     
    res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })
    
})

Now, we try John Smith again:

This time we have an improvement and we get this object in the console on the server-side:

{ first_name: 'John', last_name: 'Smith' }

We do not see Hello John Smith! on the client-side, so the server-side code fails to render it to the ejs variable word, when we use fetch() with the method set to POST. Remember, the server-side code worked with HTML form, when method = "POST" was set in the tag.

Also, I still get this error message in the console on the client-side (Chrome dev tool):

(index):68 SyntaxError: Unexpected token < in JSON at position 0

Using the Chrome dev tool, this error can be traced back to the following line of code in the above-given JavaScript code:

 console.error(error);

Using Chrome dev tool under Networking/Fetch/XHR/Payload, I see the following:

{first_name: "John", last_name: "Smith"}
first_name: "John"
last_name: "Smith"

Seemingly, the above code with fetch() is successful in sending the data to the server-side but the following part of the server-side code fails:

 res.render('index5',
    {
        word: `Hello ${req.body.first_name} ${req.body.last_name}!`
    })

Clearly, I have to find a better understanding of how the data goes back and forth between the client-side and the server-side. While I continue working on this, I appreciate it if you could help me find out what I am missing and if you could suggest a quick fix for the above-given code.

Best regards,

Eric

Update May 4, 2022

If I change

return response.json()

in the JavaScript code (client-side) to

return response

then the error message in the console (client-side) disappears.This, however, does not solve the problem at hand: why with a regular form, node.js/express.js can render to an ejs template but with fetch() it cannot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文