提取API-状态为200的GET请求返回一个空主体

时间:2020-05-16 09:27:39

标签: javascript c# get frontend fetch

我遇到了一个很奇怪的问题。该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中与在Java语言中完全相同,因此错误就不在那里了。) 结果: https://i.stack.imgur.com/H6Pnm.png

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

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

1 个答案:

答案 0 :(得分:2)

您显示的代码中实际上没有使用正文。在记录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与调用该函数的代码进行通信,则需要返回promise链,如下所示:

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开头。 / p>


仅此而已,因为ES2018距今已有两年之久,所以在现代环境中(或者如果您正在转码),可以使用async函数,这使编写逻辑成为可能不用担心时间问题。 async函数返回诺言,让您使用await在等待诺言实现之前暂停逻辑:

aysnc 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。它返回的承诺将根据await的承诺发生的情况而定。最终,一切都很好,它的承诺将由您return的值来实现(或者在上述情况下,实现值response.json()会在结算时提供)。

您可以这样使用它(在另一个async函数内部):

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

(如果发生错误,上面代码所在的async函数将拒绝p