当前位置: 首页 > 知识库问答 >
问题:

如何处理这个fetch()TypeError?

郑正文
2023-03-14

我试图将我的fetch查询的响应状态打印到控制台(以便以后处理那些边缘情况)。但是,唯一有效的console.log调用是“违规”函数中的调用。当帐户存在于HIBP数据库中时,我没有收到任何错误,但是当帐户不在数据库中时,我收到“请求失败:类型错误:响应. 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);
            });
    }
}

共有1个答案

谈旺
2023-03-14

您的状态函数返回(promise)400秒或404秒响应的状态文本。您使用<code>获取</code>结果的promise链无法处理这种可能性;它假设它得到了响应对象。

您可能希望在400或404上拒绝,而不是解析,但如果不是,则需要在<code>中分支,然后</code>处理程序将读取JSON。

您使用违规行为的代码也在覆盖相同的wide并重复附加它;它最终只会附加一次,并包含最后一个违规行为的信息。并且append函数没有提供任何有用的抽象,而不仅仅是调用appendUNICEF

如果API真的返回404表示“无违规”(blech),那么我将去掉createNodeappend,将状态更改为:

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);
    });

另外:你的< code>status函数暗示你没有意识到< code>then(和< code>catch)创造了新的promise。如果您的< code>status函数只是用作< code>then处理程序,那么它没有理由创建任何promise。它应该只是返回一个值(由< code>then创建的promise将解析该值)或抛出一个错误(由< code>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);
    }
}

(我删除了每个分支中< code>return之后的< code>console.log行,因为它们是不可访问的。)

 类似资料:
  • home.html 书中让我输入的原始代码被注释掉(减去一个implicity_wait)。在我之前阅读这本书的时候,代码运行没有问题,但我一直不停地遇到这个StaleElement错误,无法找到克服它的方法。有人有什么建议吗?

  • 问个基础问题噻 这个in该怎么写,怎么给参数好? PointsMapper.java里

  • 处理成 [11,1201,1304,1305]

  • 我想在一个操作符中接收和处理三个流。例如,Storm中实现的代码如下: <代码>生成器。setBolt(“C\u螺栓”,C\u螺栓(),parallelism\u提示)。字段分组(“A\u bolt”,“TRAINING”,新字段(“word”))。字段分组(“B\U螺栓”,“分析”,新字段(“word”))。所有分组(“A\U螺栓”、“总和”) 在Flink中,实现了和的处理: 但我不知道如何添

  • 我是JPA的新手,有一个关于如何处理实体的问题。在我的例子中,我有3个实体:用户、组和事件。 一个事件总是属于一个组。这意味着有一个OneToMulti-Relation。一个用户可以订阅多个组,这意味着有一个ManyToMulti-Relation。现在我遇到麻烦的部分。一个用户也可以订阅多个事件,这意味着也有一个ManyToMulti-Relation。 现在我的问题是。我如何在我的组实体中列

  • 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求。让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始: server { listen 80; server_name example.org www.example.org; ... } server { listen 80; server_nam