【问题标题】:Fetch API - GET request with status 200 returning an empty bodyFetch API - 状态为 200 的 GET 请求返回空正文
【发布时间】:2020-09-02 04:30:00
【问题描述】:

我遇到了一个非常奇怪的问题。此 javascript 代码应该使用 GET 请求从后端获取对象。我收到的标头的状态为 200,但正文似乎是空的。

function GetAssignment() {
    assignment = fetch(GetAssignmentURL,
        {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                
            }
        })
        .then((response) => {
            if (response.status == 200) {
                console.log(response);
                return response.json();
            }
            else
            {
                throw `error with status ${response.status}`;
            }
        })
        
        .catch((exception) => {
            console.log(exception);
        }); 
}

回应: https://i.stack.imgur.com/B3pfo.png

现在,我用 Postman 尝试了同样的事情,它在这里工作得很好。 (我检查了调用后端的 URL,它在 Postman 中和在 Javascript 中完全一样,所以错误并不存在。) 结果: https://i.stack.imgur.com/H6Pnm.png

所以,我想知道我的 Javascript 代码有什么问题。我调试了后端,当我使用 Javascript 调用它时,它确实返回了一个对象,就像它应该的那样。我一直以这种方式完成 GET 请求,但现在突然之间,响应主体在我的应用程序的前端被阻塞了。

有人遇到过同样的问题吗?

【问题讨论】:

    标签: javascript c# get frontend fetch


    【解决方案1】:

    您显示的代码中没有任何内容实际上是使用正文。在告诉它读取正文之前,您正在记录 response,而您的 assignment 变量只是具有来自 fetch 的承诺,它不会尝试对它做任何事情。

    要查看正文,您需要查看来自json 的promise 的履行值(这将做两件事:1. 读取正文,以及 2. 从 JSON 中解析它)。

    例如:

    function GetAssignment() {
        fetch(GetAssignmentURL,                 // *** No `assignment =` on this line
            {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    
                }
            })
            .then((response) => {
                if (response.status == 200) {   // *** This can be just `if (response.ok) {`
                    console.log(response);      // *** This is premature
                    return response.json();
                }
                else
                {
                    throw `error with status ${response.status}`;
                }
            })
            .then(assignment => {               // ***
                // ...use `assignment` here...  // ***
            })                                  // ***
            .catch((exception) => {
                console.log(exception);
            }); 
    }
    

    但是:如果目标是将assignment 传递给调用函数的代码,则需要返回承诺链,如下所示:

    function GetAssignment() {
        return fetch(GetAssignmentURL,
            {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    
                }
            })
            .then((response) => {
                if (response.status == 200) {   // *** This can be just `if (response.ok) {`
                    console.log(response);      // *** This is premature
                    return response.json();
                }
                else
                {
                    throw `error with status ${response.status}`;
                }
            });
    }
    

    使用它的代码会这样使用它:

    GetAssignment()
    .then(assignment => {
        // ...use `assignment` here...
    })
    .catch(error => {
        // handle/report error
    });
    

    旁注:如果GetAssignment 不打算用new 调用,那么JavaScript 中绝大多数常见的约定是以小写字母开头:getAssignment


    只是把它放在那里,因为 ES2018 是几年前的事了,在现代环境中(或者如果你正在编译)你可以使用 async 函数,这使得编写你的逻辑而不用担心和时间一样多。 async 函数返回 Promise,并让您使用 await 在等待 Promise 解决时暂停您的逻辑:

    async function getAssignment() {
        const response = await fetch(GetAssignmentURL, {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                
            }
        });
        if (!response.ok) {
            throw `error with status ${response.status}`;
        }
        return response.json();
    }
    

    在上面,对fetch 的调用是同步发生的,但是函数会挂起自己等待结果并返回一个promise。它返回的承诺将根据它awaits 的承诺发生的情况来解决。最终,一切顺利,它的承诺会以您return 的值实现(或者在上述情况下,实现值response.json() 在结算时提供)。

    你会像这样使用它(在另一个 async 函数中):

    const assignment = await getAssignment();
    // ...use `assignment` here...
    

    (如果有错误,上面代码所在的async函数会拒绝promise)

    【讨论】:

    • @MathiasGielen - 很高兴有帮助。请注意时间:GetAssignmentfetch 操作完成之前返回。我之所以提到它,是因为在您之前删除的评论中,您似乎没有意识到这一点。 :-) 编码愉快!
    • 是的,那是另一回事...当函数到达 response.json() 时,它会停止并跳转到我声明分配并使用其属性执行操作的部分。当然,例外是说我不能用空值做事。 之后,它到达了.then,我的变量在此处接收响应正文的值,但到那时为时已晚。如何在函数返回之前将响应正文分配给我的变量?
    • @MathiasGielen - 你真的不能,你必须像上面那样做。更多:stackoverflow.com/questions/14220321/…async 函数为它提供了(很多)更好的语法。
    • 我搞定了。将我的几乎全部代码粘贴到 .then 中。使用 if 函数,我检查分配是否为空。如果是这样:它将跳过所有内容并继续执行不会使其余部分崩溃的函数之外的代码。随着时间的推移,.then 将再次被调用,这次是一个值,因此代码将被执行。 :-)
    猜你喜欢
    • 1970-01-01
    • 2015-11-14
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2021-09-21
    • 2023-02-07
    • 2020-04-28
    相关资源
    最近更新 更多