【发布时间】:2021-08-30 03:15:57
【问题描述】:
我一直在尝试将搜索结果导出到 Excel 文件(类型 .xls),在此之前,我一直在使用纯 PHP 并且它可以工作。
但是,我的客户要求有“实时搜索”效果,所以我不得不转向 AJAX。
这里是起点:用户点击“导出”按钮,然后在javascript中(在主php文件viewdata.php中):
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
....
$(document).ready(function () {
var guid = <?php echo $guid ?>;
var date = document.getElementById("cbXDate").value;
var key = document.getElementById("cbsearch").value;
console.log("GUID: '" + guid + "', Date: '" + date + "' Key: '" + key + "'");
$.post("export_contacts.php",
{ sGuid: guid, sDate: date, sKey: key },
function () { console.log("Complete"); } );
});
cbXDate 是一个 date 类型的输入字段,让用户可以选择一个日期来导出数据,而 cbsearch 是一个包含搜索关键字的文本输入字段。添加控制台命令以查看代码执行的位置。
在export_contact.php中:
<?php
echo '<script> console.log("Export PHP activated."); </script>';
?>
我删除了 PHP MySQL 数据选择代码只是为了调试问题(下面是完整的源代码)。
问题是:export_contacts.php 从未被调用。 “导出 PHP 已激活”消息从未在控制台中弹出。控制台仅显示数据值和“已完成”,即从未调用 export_contacts.php。
输出:
GUID: '0001', Date: '2021-08-01' Key: 'Jo'
Complete
出于好奇,我将 $.post(...) 替换为 $("#export_div").load(...) 并显示了控制台消息:
$(document).ready(function () {
var guid = <?php echo $guid ?>;
var date = document.getElementById("cbXDate").value;
var key = document.getElementById("cbsearch").value;
console.log("GUID: '" + guid + "', Date: '" + date + "' Key: '" + key + "'");
$("#export_div").load("export_contacts.php",
{ sGuid: guid, sDate: date, sKey: key },
function () { console.log("Complete"); } );
});
输出:
GUID: '0001', Date: '2021-08-01' Key: 'Jo'
Export PHP activated.
Complete
但这不是我想要的,我想将输出写入文件,而不是在网页的 div 中显示它们。但是,“export_div” div 中显示的数据是正确的,但是 header 部分没有运行,我知道 header() 调用的古怪之处,但是在 header() 调用之前我没有输出任何东西(除非从调用 viewdata.php 文件也算吗?),这里是完整的 export_contacts.php 源代码:
<?php
include("./php/auth.php");
$guid = $_POST['sGuid'];
$date = $_POST['sDate'];
$skey = $_POST['sKey'];
$searchKey = $_POST['sKey'];
if($searchKey == "")
{
$skey = "'%'";
}
else
{
$skey = "'%".$searchKey."%'";
}
$sql = "SELECT *, FROM_UNIXTIME(ROUND((date / 1000), 0) + 46800) AS date
FROM contacts
WHERE owner = '$guid' AND contact <> ''
AND (contact LIKE $skey OR name LIKE $skey) ";
if(!empty($date))
{
"AND date >= '$date' ";
}
$sql .= "ORDER BY contact;";
if($result = mysqli_query($link, $sql))
{
$columnHeader = '';
$columnHeader = "Owner" . "\t" . "Contact" . "\t" . "Name" . "\t" . "SaveDate" . "\t";
$setData = '';
while($rows = mysqli_fetch_assoc($result))
{
$rowData = '';
foreach ($rows as $value)
{
$value = '"' . $value . '"' . "\t";
$rowData .= $value;
}
$setData .= trim($rowData) . "\n";
}
// in case of .load() used,
// code works up until this point
// code doesn't work since here...
header("Content-type: application/xls");
header("Content-Disposition: attachment; filename=contact_".$guid.".xls");
header("Pragma: no-cache");
header("Expires: 0");
echo ucwords($columnHeader) . "\n" . $setData . "\n";
// until here
// this will show in console in case of .load() used
echo '<script> console.log("Export PHP activated."); </script>';
die();
}
else
{
echo "<script>window.alert('ERROR: '".mysqli_error($link).")</script>";
}
include("./php/cleanup.php");
?>
此代码在纯 PHP 版本中运行。我不知道为什么这个 header() 部分在这里不起作用,可能是因为它的输出被重定向到了 div?
为了清楚起见,我的问题是:“为什么 $.post(...) 不调用 PHP 文件,而 $("#export_div").load(...) 调用了?”。
header() 部分只是一个子问题,忽略它也没问题。
【问题讨论】:
-
$.post()只是向给定的 URL 发出 HTTP 请求。它不会加载内容,这就是为什么您永远不会在控制台中看到“导出 PHP 已激活”的原因。 PHP 文件在服务器上执行,但输出被忽略。您写了 “我想将输出写入文件,而不是将它们显示在网页的 div 中”,但我没有看到任何写入文件的代码。相反,看起来您正在输出一个带有 HTTP 标头的 HTML 页面。那么是哪一个:在浏览器中显示输出(在新选项卡、当前选项卡或<div>中),还是将输出发送到文件? -
感谢您的回复,那么,如果我想调用一个php文件应该怎么做:1)查询数据,2)将数据写入文件,3)下载文件到本地个人电脑?我的客户非常讨厌以 php 方式提交表单导致的页面加载...该文件是在 header() 调用中编写的(我真的不知道它是如何工作的,我只是使用了从教程站点找到的任何内容,只要我可以下载文件,这对我有好处。)。我应该使用 $.ajax() 吗?
-
您根本不需要 Javascript 或 AJAX,也不需要“将数据写入文件”。只需将表单 POST 发送到发送标头的 URL,然后是文件的内容,这似乎您已经完成了。
Content-Disposition: attachment标头将强制浏览器保存文件,并且您所在的原始页面不会更改。这就是你想要的吗? -
啊,现在我明白了……我试图过度设计我的网页……真傻。我对表单标签中的 $.post() 和 METHOD='POST' 感到困惑,而忽略了 ACTION='some_php_file' 部分......谢谢你为我清理这个,所有的教程网站,包括 w3school 都没有'没有清楚地解释 $.post() 在做什么,至少我看不到......
-
警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDO 或MySQLi 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your data。 Escaping is not enough!
标签: javascript php html ajax