为什么 ajax 'application/json' 要运行 PHP 代码两次
Why do an ajax `application/json` run PHP code twice?
我正在尝试将JSON数据从JavaScript发布到PHP。您可以使用任一方式执行此操作
Content-Type: application/json
或
Content-Type: application/x-www-form-urlencoded
两者都有效,但我很难让第一个工作。原因是我错过了内容类型为 application/json
时 PHP 脚本似乎运行了 2 次。
我很惊讶,想知道发生了什么。谁能解释一下发生了什么以及如何处理它?(有一些相关的问题,但似乎没有一个答案观察到这种行为。
这是我的测试代码。首先启动PHP内置服务器:
php.exe -S localhost:7000
然后在该目录中使用以下代码创建文件test1.php
:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
header("Content-Type: application/json");
function writeStdErr($msg) { $fh = fopen('php://stderr','a'); fwrite($fh, $msg); fclose($fh); }
writeStdErr("'n'nI am here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'n");
$e = stripslashes(file_get_contents("php://input"));
writeStdErr("e=".$e."'n");
if (strlen($e) > 0) echo $e;
现在从网络浏览器控制台(我正在使用谷歌浏览器)进行ajax调用:
function test1(j) {
url = "http://localhost:7000/test1.php";
type = "application/x-www-form-urlencoded";
if (j) type = "application/json";
xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", type);
xhr.addEventListener("readystatechange", function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.email + ", " + json.password)
}
});
var data = JSON.stringify({"email":"hey@mail.com","type":type});
xhr.send(data);
console.log("now sending >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", url, type);
}
test1(false)
控制台中的输出正是我所期望的:
I am here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
e={"email":"hey@mail.com","type":"application/x-www-form-urlencoded"}
现在改为使用 applicaion/json
进行 ajax 调用,即 test1(true)
.输出现在为:
I am here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
e=
I am here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
e={"email":"hey@mail.com","type":"application/json"}
如您所见,PHP 代码已经运行了两次。第一次没有输入php://input
.
为什么???这应该如何在 PHP 中处理?
在这里借用了一些代码:将 JSON 发送到服务器并检索 JSON 作为回报,没有 JQuery
以下是一些相关问题:要在 Ajax 请求中运行两次的代码,在 php 中运行卷曲两次,https://stackoverflow.com/questions/24373623/ajax-request-help-code-gets-created-twice,使用 Yii 2 提交两次 Ajax 表单
这个问题(这里投票最高的问题之一)当然是相关的,但没有什么可说的,为什么PHP代码运行两次:
正确的 JSON 内容类型是什么?
我发布了这个答案,但解决这个问题的人实际上是Roman Shtylman,请看他今天(2015-01-13)对CORS飞行前的评论。
规则似乎是,如果您使用 application/x-www-form-urlencode
,则没有 CORS 预检,但如果您使用 application/json
就有:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
因此,如果使用"错误"标头(即 application/x-www-form-urlencode
),然后有人建议:
https://remysharp.com/2011/04/21/getting-cors-working
但。。。然后是缓存:
http://www.html5rocks.com/en/tutorials/cors/
如果这种缓存真的发生是另一个问题。我完全不知道这个问题的答案。:-(
你的javascript代码中有一些语法错误(比如缺少括号)。此外,您应该使用"var"来声明变量以将范围限制为函数。也许这会导致这种奇怪的行为。更正 javascript 代码后,我无法重现您提到的错误 => 无论 test1 的参数设置为 true 还是 false,我都只有一个错误日志条目。
这是更正后的代码 - 试一试:
function test1(j) {
var url = "http://localhost:7000/test1.php";
var type = "application/x-www-form-urlencoded";
if (j) {
type = "application/json";
}
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", type);
xhr.addEventListener("readystatechange", function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.email + ", " + json.type)
}
});
var data = JSON.stringify({"email":"hey@mail.com","type":type});
xhr.send(data);
console.log("now sending >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", url, type);
}
test1(false);
编辑:
啊,对不起,我的错。我没有读到您从 javascript 控制台运行脚本。我将其嵌入到通过浏览器调用的 php 文件中。所以这不是一个跨域请求,这就是它对我有用的原因。
我现在能够重现您的问题。如您提供的链接中所述,您应该检查请求的 HTTP 方法是否是"选项"请求 =>如果是,只需返回标头。
关于缓存问题:您可以通过"访问控制最大期限"标头将预检缓存期限设置为零。
这是应该工作的整个 php 代码:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
header("Content-Type: application/json");
header("Access-Control-Max-Age: 0");
if ($_SERVER['REQUEST_METHOD'] != 'OPTIONS') {
function writeStdErr($msg) {
$fh = fopen('php://stderr','a');
fwrite($fh, $msg);
fclose($fh);
}
writeStdErr("'n'nI am here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'n");
$e = stripslashes(file_get_contents("php://input"));
writeStdErr("e=".$e."'n");
if (strlen($e) > 0) echo $e;
}
?>
- 如何在php变量中嵌入JQuery代码
- php代码在textbox更改事件上显示null
- 在CodeIgniter视图中将Javascript或jQuery代码作为PHP文件编写可以吗
- 如何检查这个代码点火器php函数是否工作,该函数是否在ajax url中使用
- 使用PHP来阻止用户下载代码,但代码占用cpu
- 使用解析为javascript源的.php,如何使用条件语句将javascript代码封装在php括号之间
- 无法运行php代码,有角度路由问题
- php javascript代码从javascript调用php函数
- jquery中的PHP代码不起作用
- 如何在脚本部分使用php部分代码中的变量
- 获取PHP代码中日期选择器的值
- PHP代码古埃及乘法javascript
- 使用php或javascript根据某种url代码更改网页中的图片
- 代币违法;PHP内部JavaScript代码
- PHP代码中实现的JavaScript |if语句不起作用
- HTML 看不到 Javascript 代码;PHP 代码中的执行中断而没有错误
- 带有哈希密码的代码 PHP 无法工作
- 通过ajax或直接输出的行业标准代码PHP和JSON数据
- 检查MySQL数据库并添加代码PHP
- 将回显的HTML代码(PHP)追加到Javascript