我想在鼠标单击后通过使用AJAX和CORS跨域POST一个字符串,并且当POST成功时将该字符串用作SESSION变量。当ajax触发done()事件时,我想打开一个新的选项卡到我们之前发布的域,并使用SESSION变量。
我想要达到的目标,总结
- 用户在站点a
- 站点A向站点B上的页面A发出POST请求,希望将字符串发送到 站点B上的
- 页面A将字符串存储在SESSION变量 中。
- 成功后,浏览器打开B站点B页的新选项卡
- 页面B在站点B查找SESSION变量并使用它,如果存在
尽管我最初计划用SharedWorker支持来解决这个问题,但似乎不太适合它。仅使用URL参数/GET也是不可能的,因为我担心数据的大小会变得太长。
我有什么
php/receive-post.php
on域B
<?php
$origin = $_SERVER['HTTP_ORIGIN'];
if ($origin == 'http://site.a.com') {
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, Cache-Control');
if (isset($_POST)) {
session_start();
$_SESSION['string'] = $_POST['string'];
echo json_encode($_SESSION['string']);
session_write_close();
}
}
域B上index.php
的相关代码
<?php
$string;
session_start();
var_dump($_SESSION);
if (isset($_SESSION['string'])):
$string= $_SESSION['string'];
else:
$string= 'I like bananas';
endif;
session_write_close();
echo $string;
?>
和域A的脚本(jQuery)
$("a").click(function(e) {
e.preventDefault();
var href = $(this).attr('href');
postString($("textarea").serialize(), href);
});
function postString(myString, href) {
$.ajax({
type: 'POST',
url: 'http://domain.a.com/receive-post.php',
crossDomain: true,
data: myString,
headers: {
'cache-control':' no-cache'
}
}).done(function(data) {
console.log(data);
}).fail(function(a, b, c) {
console.log(a + b + c);
}).always(function() {
console.log("always");
var newTab = window.open(href, '_blank');
if (newTab) {
newTab.focus();
} else {
alert('Your browser blocked opening a new window.');
}
});
}
会发生什么应该发生的是,在单击域A上的链接后,打开一个新选项卡,并在那里使用de SESSION变量。然而,事实并非如此。
数据的post工作,因为我可以在域B的控制台中验证SESSION变量的返回值确实设置了。新选项卡也被打开。但是,在该页上没有使用/设置SESSION变量。var_dump($_SESSION)
返回一个空数组,这意味着没有设置SESSION变量。
为什么?为什么SESSION变量不在域B上从A页携带到B页?我如何使它可用?
您需要添加withCredentials
(参见jQuery)。ajax docs, xhrFields),否则cookie将不会发送/接受跨域请求。
XMLHttpRequest。withCredentials属性是一个布尔值,它指示是否应该使用诸如cookie、授权头或TLS客户端证书之类的凭据来发出跨站点访问控制请求。[…]此外,此标志还用于指示何时在响应中忽略cookie。
正如您所说,需要将Access-Control-Allow-Credentials: true
添加到来自远程域的响应中,以告诉浏览器允许在对该URL的跨域请求中包含凭据。