如果我的 PHP 代码中出现警告,为什么 xhr.response 设置为 null?

问题描述 投票:0回答:1

澄清一下:.php 文件是我教授的,不会被更改。 问题出现是因为第 186 行的

$VALORES
未初始化,我已经将它发给了我的教授。

这是代码:

  • nueva.html:
<form onsubmit="crearPublicacion(event);">
    <div>
        <label>Título:</label>
        <input type="text" name="titulo">
    </div>
    <div>
        <label>Texto:</label>
        <textarea name="texto"></textarea>
    </div>
    <div>
        <label>Zona:</label>
        <input type="text" name="zona">
    </div>
    <div id="fotos">
        <div>
            <input type="file" name="fotos[]" accept="image/*">
            <textarea name="descripciones[]"></textarea>
        </div>
        <div>
            <input type="file" name="fotos[]" accept="image/*">
            <textarea name="descripciones[]"></textarea>
        </div>
        <div>
            <input type="file" name="fotos[]" accept="image/*">
            <textarea name="descripciones[]"></textarea>
        </div>
        <div>
            <input type="submit">
        </div>
    </div>
</form>
  • nueva.js:
function crearPublicacion(evt) {
    evt.preventDefault();   // Cancela el comportamiento por defecto

    let xhr = new XMLHttpRequest(),
        url = 'api/publicaciones',
        fd  = new FormData(evt.currentTarget),
        usu = JSON.parse(sessionStorage['_datos_']),
        auth = `${usu.LOGIN}:${usu.TOKEN}`;
    
    xhr.open('POST', url, true);
    xhr.responseType = 'json';
    xhr.onload = (evt) => {
        let r = xhr.response;

        console.log(r);
    };
    xhr.setRequestHeader('Authorization', auth);
    xhr.send(fd);
}
  • publicaciones.php:
<?php
require_once('../inc/config.php'); // Constantes, etc ...
require_once('../inc/database.php');

$db    = new Database();
$dbCon = $db->getConnection();
$dbCon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

header("Access-Control-Allow-Orgin: *");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");

$RECURSO = explode("/", substr($_GET['prm'],1));
$headers = apache_request_headers();
if(isset($headers['Authorization']))
    $AUTORIZACION = $headers['Authorization'];
elseif (isset($headers['authorization']))
    $AUTORIZACION = $headers['authorization'];

if(!isset($AUTORIZACION))
{ // Acceso no autorizado
  $RESPONSE_CODE    = 403;
  $R['RESULTADO']   = 'ERROR';
  $R['CODIGO']      = $RESPONSE_CODE;
  $R['DESCRIPCION'] = 'Falta autorización';
}
else
{
  $R             = [];  // Almacenará el resultado.
  $RESPONSE_CODE = 200; // código de respuesta por defecto: 200 - OK
  $PARAMS = $_POST;
  list($login,$token) = explode(':', $AUTORIZACION);

  if( !$db->comprobarSesion($login,$token) )
  {
    $RESPONSE_CODE    = 401;
    $R['RESULTADO']   = 'ERROR';
    $R['CODIGO']      = $RESPONSE_CODE;
    $R['DESCRIPCION'] = 'Error de autenticación.';
  }
  else
  {
    $ID = array_shift($RECURSO);
    try{
      $dbCon->beginTransaction();
      if(!is_numeric($ID)) // NUEVO REGISTRO
      { // Si no es numérico $ID es porque se está creando un nuevo registro
        $titulo        = $PARAMS['titulo'];
        $texto         = nl2br($PARAMS['texto'],false);
        $zona          = $PARAMS['zona'];
        $descripciones = $PARAMS['descripciones'];

        $mysql = 'select * from zona where nombre=:ZONA';
        $RESPUESTA = $db->select($mysql, [':ZONA'=>$zona]);
        if( $RESPUESTA['CORRECTO'] ) // execute query OK
        {
          if(count($RESPUESTA['RESULT']) > 0)
          { // encontrado
            $idZona = $RESPUESTA['RESULT'][0]['id'];
          }
          else
          { // No existe la zona. Hay que crearla.
            $mysql = 'insert into zona(nombre) values(:NOMBRE)';
            if( $db->executeStatement($mysql, [':NOMBRE'=>$zona]) )
            {
              $mysql = 'select max(id) as idZona from zona';
              $RESPUESTA = $db->select($mysql, $VALORES);
              if( $RESPUESTA['CORRECTO'] ) // execute query OK
              {
                if(count($RESPUESTA['RESULT']) > 0)
                { // encontrado
                  $idZona = $RESPUESTA['RESULT'][0]['idZona'];
                }
              }
            }
          }
        }

        $mysql  = 'insert into publicacion(titulo,texto,idZona,autor) ';
        $mysql .= 'values(:TITULO,:TEXTO,:ID_ZONA,:AUTOR)';
        $VALORES             = [];
        $VALORES[':TITULO']  = $titulo;
        $VALORES[':TEXTO']   = $texto;
        $VALORES[':ID_ZONA'] = $idZona;
        $VALORES[':AUTOR']   = $login;

        if( $db->executeStatement($mysql, $VALORES) )
        {
          $mysql = "select MAX(id) as id_pub from publicacion";
          $RESPUESTA = $db->select($mysql);
          if($RESPUESTA['CORRECTO'])
          {
            $ID = $RESPUESTA['RESULT'][0]['id_pub'];

            $RESPONSE_CODE    = 201;
            $R['RESULTADO']   = 'OK';
            $R['CODIGO']      = $RESPONSE_CODE;
            $R['DESCRIPCION'] = 'Registro creado correctamente';
            $R['ID']          = $ID;
            $R['TITULO']      = $titulo;
            $R['FOTOS']       = $fotos;
          }
          else
            $ID = -1;
        }
        else
        {
          $RESPONSE_CODE    = 500; // INTERNAL SERVER ERROR
          $R['RESULTADO']   = 'ERROR';
          $R['CODIGO']      = $RESPONSE_CODE;
          $R['DESCRIPCION'] = 'Error indefinido al crear el nuevo registro';
        }
      }
      $dbCon->commit();
    }catch(Exception $e){
      echo $e;
      $dbCon->rollBack();
    }
  }
}
$dbCon = null;
http_response_code($RESPONSE_CODE);
echo json_encode($R);
?>
  • 数据库.php:
<?php
class Database{
    private $HOST              = "127.0.0.1";
    private $DB_DATABASE_NAME  = "websocial";
    private $DB_USERNAME       = "pcw";
    private $DB_PASSWORD       = "pcw";
    public  $conn;

    public function __construct() {...}

    public function select($query = "" , $params = [])
    {
        $result = false;
        $RESPUESTA = [];

        try {
            $stmt = $this->conn->prepare( $query );
            if($stmt === false) {
                throw New Exception("Unable to do prepared statement: " . $query);
            }

            $stmt->execute($params);

            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $stmt->closeCursor();
            $RESPUESTA['CORRECTO'] = true;
        } catch(Exception $e) {
            // throw New Exception( $e->getMessage() );
            $RESPUESTA['CORRECTO'] = false;
            $RESPUESTA['ERROR'] = $e->getMessage();
        }

        $RESPUESTA['RESULT'] = $result;

        return $RESPUESTA;
    }

    public function executeStatement($query = "", $params = [])
    {
        $retVal = false;
        try {
            $stmt = $this->conn->prepare( $query );
 
            if($stmt === false) {
                throw New Exception("Unable to do prepared statement: " . $query);
            }
 
            if( $params )
                $retVal = $stmt->execute($params);
            else
                $retVal = $stmt->execute();

        } catch(Exception $e) {
            throw New Exception( $e->getMessage() );
        }   

        return $retVal;
    }

}
?>

如您所见,在第 186 行调用

$VALORES
时,
select
(publicacion.php) 尚未初始化(这是每当我尝试在 Postman 中执行 POST 时它给我的警告)。解决方案就像完全删除 $VALORES 一样简单。

给大家一个思路,这是预期的结果:

{
    "RESULTADO": "OK",
    "CODIGO": 201,
    "DESCRIPCION": "Registro creado correctamente",
    "ID": 109,
    "TITULO": "",
    "FOTOS": []
}

但是只有当“zona”的值在数据库中不存在时才会发生这种情况(如果它已经存在,那么响应总是上面的):

  • 邮递员:

警告:第 186 行 C:\xampp\htdocs\pcw\practica2 pi\post\publicaciones.php 中的未定义变量 $VALORES

{
    "RESULTADO": "OK",
    "CODIGO": 201,
    "DESCRIPCION": "Registro creado correctamente",
    "ID": 109,
    "TITULO": "",
    "FOTOS": []
}
  • VSCode 调试器 / Web DevTools 中的 JS 控制台:
null

正如我之前所说,我已经解决了这个问题,但我的问题是为什么会发生以及具体发生在哪里。

什么时候我的

xhr.response
设置为
null
?我能找到的唯一解释是,即使代码运行正常(即没有陷入 catch 和 throw 语句并且根本没有退出),发出警告也会以某种方式使响应无效。

javascript php html xmlhttprequest
1个回答
0
投票

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType#value:

当将 responseType 设置为特定值时,作者应确保服务器实际发送与该格式兼容的响应。如果服务器返回的数据与设置的 responseType 不兼容,则 response 的值为 null。

使用

xhr.responseType = 'json';
你告诉浏览器,响应将是 JSON,并且它应该自动为你解析它。

但是“随机 PHP 警告消息后跟一些 JSON”不是有效的 JSON。因此它将您的响应值设置为 null。

© www.soinside.com 2019 - 2024. All rights reserved.