Я пытаюсь асинхронно загрузить файл через javascript в фоновом режиме. Я обновляю нашу библиотеку, чтобы использовать fetch вместо XHR. Запрос XHR работает правильно, и на вкладке сети отображается ожидаемый ответ, который в настоящее время представляет собой просто var_dump ($ _ FILES) и var_dump ($ _ POST).
Когда я по какой-то причине выполняю тот же вызов с fetch, PHP останавливается при создании сеанса. Я выделил это до строки:
$session = new Session;
Вот очищенная версия XHR, которая возвращает оба этих PHP массива, заполненных правильно
var request = {},
url = "../../lib/upload.php",
formData = new FormData;
formData.append(
"PHP_SESSION_UPLOAD_PROGRESS", phpSessionKey // upload session key var
);
formData.append(
"uploaded_file", this.file.baseFile // file object from an upload input
);
formData.append(
"pageid", 1234
);
request = new XMLHttpRequest();
request.open("POST", url, true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log(responseText);
}
}
request.send(formData);
Вот сопоставимая выборка, обратите внимание, что я смотрел на заголовки и все остальное, которые кажутся идентичными, но я не могу понять, почему версия выборки выходит в этой строке создания сеанса.
let formData = new FormData(),
phpSessionKey = Uploader.pageid + "_" + this.file.name,
that = this;
formData.append(
"PHP_SESSION_UPLOAD_PROGRESS", phpSessionKey
);
formData.append(
"uploaded_file", this.file.baseFile
);
formData.append(
"pageid", Uploader.pageid
);
fetch('../lib/upload.php', {
method: 'POST',
body: formData
});
Эта выборка на вкладке сети ничего не возвращает, и, зайдя и прокомментировав затем некомментированные строки, я сузил проблему до строки создания сеанса при загрузке. php. Я, честно говоря, просто растерялся из-за того, почему это происходит в данный момент, пытаясь довести до JS стандартов до сих пор было довольно гладко.
РЕДАКТИРОВАТЬ
Вот класс сеанса в PHP:
class Session {
private $user_id;
private $last_login;
private $database;
public $user;
public $username;
public const MAX_LOGIN_AGE = 60 * 60 * 24; // 1 day
// Constructor which attaches pseudo magic methods to php sessions
public function __construct()
{
session_set_save_handler(
array($this, '_open'),
array($this, '_close'),
array($this, '_read'),
array($this, '_write'),
array($this, '_destroy'),
array($this, '_clean')
);
session_start();
$this->check_stored_login();
}
public function _open()
{
if ($session_db = db_connect(DB_DEV)) {
$this->database = $session_db;
return true;
}
return false;
}
public function _close()
{
// print "Session closed.\n";
return $this->database->close();
}
public function _read($id)
{
$id = $this->database->escape_string($id);
// print "Session read.\n";
// print "Sess_ID: $id\n";
$sql = "SELECT data
FROM sessions
WHERE id = '{$id}'";
if ($result = $this->database->query($sql)) {
if ($result->num_rows) {
$record = $result->fetch_assoc();
return $record['data'];
}
}
return '';
}
public function _write($id, $data)
{
$access = time();
$id = $this->database->escape_string($id);
$access = $this->database->escape_string($access);
$data = $this->database->escape_string($data);
// print "Session value written.\n";
// print "Sess_ID: $id\n";
// print "Data: $data\n\n";
$sql = "REPLACE
INTO sessions (`id`, `access`, `data`)
VALUES ('{$id}', '{$access}', '{$data}')";
$this->database->query($sql);
return true;
}
public function _destroy($id)
{
$id = $this->database->escape_string($id);
// print "Session destroy called.\n";
$sql = "DELETE
FROM sessions
WHERE id='{$id}'";
return $this->database->query($sql);
}
public function _clean($max)
{
$old = $time() - $max;
$this->database->escape_string($old);
$sql = "DELETE
FROM sessions
WHERE access < '{$old}'";
return $this->database->query($sql);
}
public function login($user)
{
if ($user) {
// prevent session fixation attacks
session_regenerate_id();
$this->user_id = $_SESSION['user_id'] = $user->id = $user->id;
$this->username = $_SESSION['username'] = $user->first_name;
$this->last_login = $_SESSION['last_login'] = time();
$this->user = $_SESSION['user'] = $user;
$_SESSION['search_text'] = '';
$_SESSION['search_product_id'] = '';
$args["last_login"] = date("Y-m-d H:m:s");
$user->merge_attributes($args);
$user->save();
}
}
public function is_logged_in()
{
if (!isset($this->user_id) || !$this->last_login_recent()) {
redirect_to(url_for('/index.php?logout'));
}
return true;
}
public function logout()
{
unset($_SESSION['user_id']);
unset($_SESSION['username']);
unset($_SESSION['last_login']);
unset($_SESSION['user']);
unset($this->user_id);
unset($this->username);
unset($this->last_login);
unset($this->user);
session_destroy();
return true;
}
private function check_stored_login()
{
if (isset($_SESSION['user_id'])) {
$this->user_id = $_SESSION['user_id'];
$this->username = $_SESSION['username'];
$this->last_login = $_SESSION['last_login'];
$this->user = $_SESSION['user'];
}
}
private function last_login_recent()
{
if (!isset($this->last_login)) {
return false;
} elseif ($this->last_login + self::MAX_LOGIN_AGE < time()) {
return false;
} else {
return true;
}
}
public function message($msg = '')
{
if (!empty($msg)) {
$_SESSION['message'] = $msg;
} else {
return $_SESSION['message'];
}
}
}
?>