JavaScript中的fetch被触发两次。

huangapple go评论59阅读模式
英文:

javascript fetch is fired double

问题

Sure, here's the translation of the code portion you provided:

我有一个简单的JavaScript函数用于获取URL并在收到响应时更新HTML页面如下所示

function post_db(self) {
   // 其他代码在这里
   async function postData() {
      const url = "fetchnewseq";
      
      const response = await fetch(url, {
        method: 'POST',
        headers: {
            'X-CSRFToken': csrftoken,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(comandi_json)
      });
      return await response.json()
    }
    
    postData().then((data) => { 
        window.location.replace(data.url); 
    });
}
post_db函数由按钮触发,如下所示:

<button onclick="post_db(this)" class="btn btn-success">Conferma</button>
在后端我使用Django管理该URL的视图如下

def fetch_new_seq(request):
    json_received = json.loads(request.body.decode("utf-8"))
    print(json_received)
    messages.success(request, "Ricevuto")
    redirect_url = reverse('newSeq')
    return JsonResponse({'url': redirect_url})

此外,我看到fetch请求两次触发,我无法理解为什么会发生,因为按钮只被点击了一次。我还在Mozilla浏览器的控制台中看到了错误Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

触发post_db的按钮位于一定数量的

元素内,如下所示:

Creazione di sequenze di movimento

<div class="row">
  <div class="d-grid gap-2 col">
    <button onclick="load_js()" class="btn btn-secondary">
      Riordina
    </button>
  </div>
  <div class="d-grid gap-2 col">
    {% csrf_token %}
    <button onclick="post_db()" class="btn btn-success">
      Conferma
    </button>
  </div>
  <div class="d-grid gap-2 col">
    <button onclick="addNewRow()" class="btn btn-primary">
      Aggiungi Movimento
    </button>
  </div>
</div>

```

Please note that the code you provided seems to contain HTML entities like &quot; and &gt;, which are typically used for encoding double quotes and greater-than signs in HTML. These entities should be decoded when using the code, but I've left them as is in the translation for clarity.

英文:

I have a simple function in javascript that fetch and URL and update the HTML page when it got a response like:

 function post_db(self) {
   // other code here
   async function postData() {
      const url = &quot;fetchnewseq&quot;
      
      const response = await fetch(url, {
        method: &#39;POST&#39;,
        headers: {
            &#39;X-CSRFToken&#39;: csrftoken,
            &#39;Content-Type&#39;: &#39;application/json&#39;
        },
        body: JSON.stringify(comandi_json)
      });
      return await response.json()
    }
    
    postData().then((data) =&gt; { 
        window.location.replace(data.url); 
    });
   }

The post_db function is fired by a button like

&lt;button onclick=&quot;post_db(this)&quot; class=&quot;btn btn-success&quot;&gt;Conferma&lt;/button&gt;

On the backend I'm using Django and the view that manages that URL is

def fetch_new_seq(request):
    json_ricevuto = json.loads(request.body.decode(&quot;utf-8&quot;))
    print(json_ricevuto)
    messages.success(request, &quot;Ricevuto&quot;)
    redirect_url = reverse(&#39;newSeq&#39;)
    return JsonResponse({&#39;url&#39;: redirect_url})

For some reason, the fetch is fired two times as I'm seeing the function on the backed with the same results two times

I can't understand why it happens tho as, the button is clicked just one

I'm also seeing on the console of Mozilla Browser I got the error Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

The button that fires the post_db is inside a certain number of divs

 &lt;div id=&quot;container&quot; class=&quot;container-fluid&quot;&gt;
  &lt;div class=&quot;container text-center&quot;&gt;
    &lt;h3&gt;Creazione di sequenze di movimento&lt;/h3&gt;
    &lt;input
      type=&quot;text&quot;
      class=&quot;form-control mt-3 mb-3&quot;
      id=&quot;titleseq&quot;
      placeholder=&quot;Inserisci Titolo&quot;
    /&gt;

    &lt;div class=&quot;row&quot;&gt;
      &lt;div class=&quot;d-grid gap-2 col&quot;&gt;
        &lt;button onclick=&quot;load_js()&quot; class=&quot;btn btn-secondary&quot;&gt;
          Riordina
        &lt;/button&gt;
      &lt;/div&gt;
      &lt;div class=&quot;d-grid gap-2 col&quot;&gt;
        {% csrf_token %}
        &lt;button onclick=&quot;post_db()&quot; class=&quot;btn btn-success&quot;&gt;
          Conferma
        &lt;/button&gt;
      &lt;/div&gt;
      &lt;div class=&quot;d-grid gap-2 col&quot;&gt;
        &lt;button onclick=&quot;addNewRow()&quot; class=&quot;btn btn-primary&quot;&gt;
          Aggiungi Movimento
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

答案1

得分: 0

我可能已经找到了问题所在。具有fetch代码的async函数位于像下面这样的for循环中:

for (var i = 0; i &lt; len_array; i++) {
  if (
    comandi_json[&quot;lista_comandi&quot;][i][&quot;comando&quot;] == &quot;&quot; ||
    comandi_json[&quot;lista_comandi&quot;][i][&quot;tempo&quot;] == null
  ) {
    console.log(&quot;Error&quot;);
    return;
  } else {
    async function postData() {
      const url = &quot;fetchnewseq&quot;;

      const response = await fetch(url, {
        method: &quot;POST&quot;,
        headers: {
          &quot;X-CSRFToken&quot;: csrftoken,
          &quot;Content-Type&quot;: &quot;application/json&quot;,
        },
        body: JSON.stringify(comandi_json),
      });
      return await response.json();
    }
    postData().then((data) =&gt; {
      window.location.replace(data.url);
    });
  }
}

很明显,每次第一个检查正确执行而没有return时,else就会被触发,并且随之触发了fetch函数多次,从而引发了问题。

将其重写到循环外部修复了问题:

for (var i = 0; i &lt; len_array; i++) {
  if (
    comandi_json[&quot;lista_comandi&quot;][i][&quot;comando&quot;] == &quot;&quot; ||
    comandi_json[&quot;lista_comandi&quot;][i][&quot;tempo&quot;] == null
  ) {
    console.log(&quot;Error&quot;);
    return;
  } 
}

async function postData() {
  const url = &quot;fetchnewseq&quot;;

  const response = await fetch(url, {
    method: &quot;POST&quot;,
    headers: {
      &quot;X-CSRFToken&quot;: csrftoken,
      &quot;Content-Type&quot;: &quot;application/json&quot;,
    },
    body: JSON.stringify(comandi_json),
  });
  return await response.json();
}
postData().then((data) =&gt; {
  window.location.replace(data.url);
});
英文:

So I may have found the issue. The async function with the fetch code was inside a for loop like:

for (var i = 0; i &lt; len_array; i++) {
  if (
    comandi_json[&quot;lista_comandi&quot;][i][&quot;comando&quot;] == &quot;&quot; ||
    comandi_json[&quot;lista_comandi&quot;][i][&quot;tempo&quot;] == null
  ) {
    console.log(&quot;Error&quot;);
    return;
  } else {
    async function postData() {
      const url = &quot;fetchnewseq&quot;;

      const response = await fetch(url, {
        method: &quot;POST&quot;,
        headers: {
          &quot;X-CSRFToken&quot;: csrftoken,
          &quot;Content-Type&quot;: &quot;application/json&quot;,
        },
        body: JSON.stringify(comandi_json),
      });
      return await response.json();
    }
    postData().then((data) =&gt; {
      window.location.replace(data.url);
    });
  }
}

Clearly, every time the first check was performed correctly without return, the else got fired and, with it, the fetch function triggered it more than once and generated the issue.

Rewriting it outside the for fixed the issue

for (var i = 0; i &lt; len_array; i++) {
  if (
    comandi_json[&quot;lista_comandi&quot;][i][&quot;comando&quot;] == &quot;&quot; ||
    comandi_json[&quot;lista_comandi&quot;][i][&quot;tempo&quot;] == null
  ) {
    console.log(&quot;Error&quot;);
    return;
  } 
 }

    async function postData() {
      const url = &quot;fetchnewseq&quot;;

      const response = await fetch(url, {
        method: &quot;POST&quot;,
        headers: {
          &quot;X-CSRFToken&quot;: csrftoken,
          &quot;Content-Type&quot;: &quot;application/json&quot;,
        },
        body: JSON.stringify(comandi_json),
      });
      return await response.json();
    }
    postData().then((data) =&gt; {
      window.location.replace(data.url);
    });

huangapple
  • 本文由 发表于 2023年6月22日 14:38:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76529163.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定