亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在React中使用窗口的beforeunload事件執行axios代碼

如何在React中使用窗口的beforeunload事件執行axios代碼

PHP
鳳凰求蠱 2023-11-03 16:47:31
我正在使用 React 和 PHP,我需要它來做一些特定的事情。我正在使用 Axios 向我的 PHP 頁面發送請求,然后更改我的數據庫。我需要更新我的 MySQL 數據庫表,如果用戶關閉頁面或瀏覽器,則將is_logged值從true更改為false 。執行此操作的代碼在窗口的beforeunload事件中設置。但是,數據庫永遠不會更新。我想要做的事情在 React 中是可能的嗎?這是我的 React 組件代碼:import React, { useState, useEffect } from 'react';import axios from 'axios';import Viewers from './Viewers';const Live = ({ match }) => {  window.addEventListener("beforeunload", () => {    axios.get('http://localhost/live-streaming-app/get_viewers.php?=' + token)      .then(response => console.log(response))  })  // Set token from url  const token = match.params.token  //Get the fullname and update logged_in to true  const [fullname, setFullname] = useState("")  useEffect(() => {    axios.get('http://localhost/live-streaming-app/get_user.php?token=' + token)      .then(response => {        setFullname(response.data.fullname)        console.log("Data", response.data)      })      .catch(error => console.log(error))    return () => {      axios.get('http://localhost/live-streaming-app/get_viewers.php?=' + token)        .then(response => console.log(response))        .catch(error => console.log(error))    }  }, [token])  //Jsx for when user is unauthorised  const rejected = (    <div className="container text-center pt-5">      <h1>Rejected Connection</h1>      <p>You are unauthorised to view this page</p>    </div>  )  let my_render = ""  if (fullname && fullname != null) {    my_render = <Viewers fullname={fullname} />  } else {    my_render = rejected  }  return my_render};export default Live;這是名為的 PHP 頁面:<?phprequire 'connect.php';$token = $_GET['token'];$sql = "UPDATE `viewers` SET `logged_in`='false' WHERE `live_token`='{$token}'";if(mysqli_query($con, $sql)){  http_response_code(201);}else {  http_response_code(422);}exit;
查看完整描述

2 回答

?
蕪湖不蕪

TA貢獻1796條經驗 獲得超7個贊

需要處理的問題:


請求是否已發送?

嘗試跑步


axios.get('http://localhost/live-streaming-app/get_viewers.php?=')

  .then(response => console.log(response))

在瀏覽器控制臺中查看控制臺中是否記錄了任何內容。還要檢查開發工具中的“網絡”選項卡,以查看是否發送了請求。如果請求已發送,則請求的發送有效。如果沒有,則說明 URL 存在一些問題,需要修復。


代幣

發送此請求


axios.get('http://localhost/live-streaming-app/get_viewers.php?=' + token)

  .then(response => console.log(response))

表示空字符串的值為token。另一方面,您的 PHP 代碼假設有一個名為 的參數token:


<?php

require 'connect.php';


$token = $_GET['token']; //This is the line which assumes that a parameter called token exists


$sql = "UPDATE `viewers` SET `logged_in`='false' WHERE `live_token`='{$token}'";

if(mysqli_query($con, $sql)){

  http_response_code(201);

}

else {

  http_response_code(422);

}


exit;

為了符合 PHP 代碼的假設,您需要指定token名為 的參數的值token:


  window.addEventListener("beforeunload", () => {

    axios.get('http://localhost/live-streaming-app/get_viewers.php?token=' + token)

      .then(response => console.log(response))

  })

上面的修復應該可以解決您所詢問的問題,但我們不要就此停止。


SQL注入

如果我從瀏覽器控制臺(或 cURL)發送此請求(不要運行它,除非您創建備份)會怎樣:


axios.get("http://localhost/live-streaming-app/get_viewers.php?token=';delete from viewers where ''='")

  .then(response => console.log(response))

?


然后你的 PHP 代碼將執行:


UPDATE `viewers` SET `logged_in`='false' WHERE `live_token`='';delete from viewers where ''=''

viewers從數據庫中刪除所有內容。使用PDO參數化您的查詢并使您的查詢免受此類攻擊。


概括

React 是一個 Javascript 框架,這意味著無論 Javascript 能做什么,你的客戶端也能做到。確實,某些功能不一定以 React 方式可用,但假設 Javascript 能夠做到這一點,那么您不必擔心這些功能是否可行。我傾向于認為,當客戶端發生很多事情時,客戶端框架將變得不太有用,并且我認為客戶端框架流行的主要原因是大多數程序員沒有意識到有多少Javascript 能夠做到的事情。我并不是說永遠不應該使用客戶端框架。我只是說,我見過程序員盲目迷戀客戶端框架和技術,最終毀掉了他們所從事的項目。因此,當您選擇客戶端技術堆棧時,值得檢查客戶端所需的功能、不使用客戶端框架實現它所需的時間以及使用您可能考慮的每個框架實現它所需的時間使用。比較兩者并考慮截止日期和財務能力。如果您找不到使用客戶端框架的明顯且很好的理由,那么我建議不要使用它。因為,歸根結底,如果在開發過程中由于某種原因您需要使用客戶端框架,您可以輕松地從不使用框架的位置轉向它。但是,如果您正在使用客戶端框架,并且事實證明它對您的項目不可行,那么重構整個項目以不使用該框架通常意味著重新實現大部分客戶端。而這種問題往往不會在緊急情況下顯現出來。


查看完整回答
反對 回復 2023-11-03
?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

無法保證事件中執行的異步操作beforeunload將會完成,axios 使用異步方式發出請求。


您或許可以使用老式的 XHR 來發出同步請求。如果您轉到標記為 的部分Adapting Sync XHR use cases to the Beacon API,他們將討論在卸載期間保持請求活動的策略,因為同步 XHR 已被棄用。


請注意,同步 HTTP 請求通常不是一個好主意,因為它們會在完成時導致頁面無響應。我不確定卸載期間同步請求的行為是什么。


同步請求示例


logUser () {

    var params = JSON.stringify({ locked_by: '' });

    let xhr = new XMLHttpRequest()

    xhr.open('PUT',Url, false) // `false` makes the request synchronous

    xhr.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem('app_access_token'))

    xhr.setRequestHeader("Content-length", params.length);

    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8")

    xhr.responseType = 'arraybuffer'

    xhr.onreadystatechange = function() {//Call a function when the state changes.

    if(xhr.readyState == 4 && xhr.status == 200) {

        alert(xhr.responseText);

    }

}


筆記


沒有可靠的方法可以在選項卡/窗口關閉時執行某些操作。這違背了“關閉”選項卡(即釋放資源)的原則。


我處理你的情況的方法是讓前端保存一些在選項卡關閉時自行消失的東西。


要么打開一個可用于許多其他目的的 websocket,當它死機并且在幾秒鐘內沒有返回時,您就知道客戶端已斷開連接,或者在選項卡打開時以及錯過了某個時間時發送常規 ping幾次 ping 操作后,您就可以安全地假設客戶端已斷開連接。


查看完整回答
反對 回復 2023-11-03
  • 2 回答
  • 0 關注
  • 296 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號