javascript - 如何处理这个 fetch() 类型错误?

标签 javascript typeerror fetch-api

我正在尝试将获取查询的响应状态打印到控制台(以便稍后处理这些边缘情况)。然而,唯一有效的 console.log 调用是“breaches”函数中的调用。当 HIBP 数据库中存在帐户时,我不会收到任何错误,但当帐户不在数据库中时,我会收到“请求失败:TypeError:response.json 不是 json 的函数”错误。我究竟做错了什么?我从 Google Web Dev 获取了错误处理代码文章。

function createNode(element) {
    return document.createElement(element);
}

function append(parent, el) {
    return parent.appendChild(el);
}

function status(response) {
    if (response.status >= 200 && response.status < 300) {
        return Promise.resolve(response)
        console.log('all is good');
    } else if (response.status == 404) {
        return Promise.resolve(response.statusText)
        console.log('no breaches');
    } else if (response.status == 400) {
        return Promise.resolve(response.statusText)
        console.log('bad req');
    } else {
        return Promise.reject(new Error(response.statusText))
    }
}

function json(response) {
    return response.json()
}

var account = document.getElementById('account'),
    results = document.getElementById('results');
account.addEventListener("keyup", keyupEvent);

function keyupEvent() {
    event.preventDefault();
    if (event.key === "Enter") {
        fetch('https://haveibeenpwned.com/api/v2/breachedaccount/' + account.value, {
                timeout: 1500,
                userAgent: 'test'
            })
            .then(status)
            .then(json)
            .then(function(breaches) {
                console.log('Status Code: ' + breaches.status);
                let span = createNode('span');
                return breaches.forEach(function(check) {
                    span.innerHTML = `${check.Name}<br/>`;
                    append(results, span)
                })

            }).catch(function(error) {
                console.log('Request failed:', error);
            });
    }
}

最佳答案

您的status函数返回( promise )400 或 404 响应的状态文本。您的 promise 链消耗 fetch result 不处理这种可能性;它假设它获取了响应对象。

您可能想要拒绝 400 或 404,而不是解决,但如果不是,您需要在 then 中进行分支。处理程序期望读取 JSON。

您使用漏洞的代码也会覆盖相同的 span并反复追加;它最终只会附加一次,包含最后违规信息。还有append函数不提供任何有用的抽象,而只是调用 appendChild .

如果 API 确实返回 404 表示“没有违规”(blech),那么我会删除 createNodeappend ,更改status对此:

function status(response) {
    if (response.ok) {
        return response.json();
    } else if (response.status === 404) { // If the API *really* returns
        return [];                        // a 404 for "no breaches"
    } else {
        throw new Error(response.statusText);
    }
}

然后:

fetch('https://haveibeenpwned.com/api/v2/breachedaccount/' + account.value, {
        timeout: 1500,
        userAgent: 'test'
    })
    .then(status)
    .then(breaches => {
        // No `return` here, the chain isn't passed on and there
        // aren't any further resolution handlers
        breaches.forEach(check => {  // Or a for-of loop
            const span = document.createElement("span");
            span.innerHTML = `${check.Name}<br/>`;
            results.appendChild(span);
        });
    }).catch(error => {
        console.log('Request failed:', error);
    });

单独:您的 status函数表明您没有意识到 then (和 catch )创建新的 promise 。你的 status 没有理由函数来创建任何 promise (如果它仅用作 then)处理程序。它应该只是返回一个值(由 then 创建的 promise 将使用该值解析)或抛出错误(由 then 创建的 promise 将因该错误而拒绝):

// This is equivalent to your current `status` function (assuming it's always
// used as a `then` callback)
function status(response) {
    if (response.ok) { // if (response.status >= 200 && response.status < 300) {
        // all okay
        return response;
    } else if (response.status == 404) {
        // no breaches
        return response.statusText;
    } else if (response.status == 400) {
        // bad request
        return response.statusText;
    } else {
        throw new Error(response.statusText);
    }
}

(我删除了每个分支中 console.log 之后的 return,因为它们无法访问。)

关于javascript - 如何处理这个 fetch() 类型错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52757338/

相关文章:

python - TypeError: * 之后的类型对象参数必须是一个序列,而不是生成器

django - 管理错误 : __str__ returned non-string (type NoneType)

javascript - 发布到 localhost 时 fetch 返回 400

javascript - Zurb Foundation 组件不工作

javascript - 更改window.open的标题

javascript - RxJS 不能与 Math.random() 配合使用

javascript - 密码值返回未定义,但使用console.log显示时,用户可以看到

python-3.x - sympy 在将无理数放入分数时返回 TypeError

javascript - API 获取失败,请求的资源上不存在 'Access-Control-Allow-Origin' header

postman 执行操作时,javascript fetch 未发布到 rest api 端点