api 呼叫的 cross-sub-domain 请求未发送 Cookie
Cookies not being sent on cross-sub-domain request on an api call
我在 https://page.domain.com 上存储了一个页面。
在这里,我使用 javascript(主要是 Bootstrap)从 https://api.domain.com 获取数据。
加载页面时,第一个调用是 "sort of" 身份验证调用,其中 return headers:
中的一个 cookie
set-cookie: oauth=emd4YWgybTJobmJnZjVrbXl2ZjdlZThiOzkzczg1YWt2YzNyZW42cjk3M2U4dXlweA==; domain=.domain.com; path=/; expires=Fri, 16 Apr 2021 11:58:07 GMT;
我可以在开发者工具 (Chrome) 中看到 cookie 已正确存储。
但是,当我进行下一个 api 调用时(例如,填写下拉列表 - bootstrap 自动完成),cookie 不在请求中。
当我在 localhost 中构建它时它工作正常(我猜是相同的 "domain")但是现在,在不同的域上具有 html 和 apis 运行,它似乎没有共享 cookie。
我认为可能是因为两个不同的域,但根据文档,当一个 cookie 设置到主域时,所有 sub-domains 应该都可以共享它。 (另外,我包括 "withCredentials" 标志)
这是初始调用的代码(并设置后续调用):
$.ajax({url: 'https://api.domain.com/get-cookie',
xhrFields: {
withCredentials: true
}
})
.done(function (response) {
$('.selectpicker').selectpicker().ajaxSelectPicker({
ajax: {
// data source
url: 'https://api.domain.com/data.json',
// ajax type
type: 'GET',
// data type
dataType: 'json',
// Use "{{{q}}}" as a placeholder and Ajax Bootstrap Select will
// automatically replace it with the value of the search query.
data: {
q: '{{{q}}}'
}
},
// function to preprocess JSON data
preprocessData: function (data) {
var i, l = data.length, array = [];
if (l) {
for (i = 0; i < l; i++) {
array.push($.extend(true, data[i], {
text : data[i].name,
value: data[i].code,
data : {
subtext: data[i].code
}
}));
localStorage.setItem(data[i].code, data[i].name);
}
}
// You must always return a valid array when processing data. The
// data argument passed is a clone and cannot be modified directly.
return array;
}
});
}
);
我正在使用 AWS API 网关和 Lambda 函数,但这应该不相关...
从 selectPicker(例如:https://api.domain.com/data.json )获取 url 并将其直接放入浏览器时,我看到正在发送 cookie。
这似乎表明问题可能出在未正确发送 headers 的 Bootstrap Select 组件中。
我不确定我是否可以让它按预期工作,或者我必须找到其他替代方案。
解决方案是在选择器请求中也包含 withCredentials:
$('.selectpicker').selectpicker().ajaxSelectPicker({
ajax: {
// data source
url: 'https://api.domain.com/data.json',
// ajax type
type: 'GET',
// data type
dataType: 'json',
// Use "{{{q}}}" as a placeholder and Ajax Bootstrap Select will
// automatically replace it with the value of the search query.
data: {
q: '{{{q}}}'
},
xhrFields: {
withCredentials: true
}
},
// function to preprocess JSON data
preprocessData: function (data) {
// ...
}
});
}
);
感谢@CBroe 在评论中提出的想法。
我在 https://page.domain.com 上存储了一个页面。 在这里,我使用 javascript(主要是 Bootstrap)从 https://api.domain.com 获取数据。 加载页面时,第一个调用是 "sort of" 身份验证调用,其中 return headers:
中的一个 cookieset-cookie: oauth=emd4YWgybTJobmJnZjVrbXl2ZjdlZThiOzkzczg1YWt2YzNyZW42cjk3M2U4dXlweA==; domain=.domain.com; path=/; expires=Fri, 16 Apr 2021 11:58:07 GMT;
我可以在开发者工具 (Chrome) 中看到 cookie 已正确存储。
但是,当我进行下一个 api 调用时(例如,填写下拉列表 - bootstrap 自动完成),cookie 不在请求中。 当我在 localhost 中构建它时它工作正常(我猜是相同的 "domain")但是现在,在不同的域上具有 html 和 apis 运行,它似乎没有共享 cookie。 我认为可能是因为两个不同的域,但根据文档,当一个 cookie 设置到主域时,所有 sub-domains 应该都可以共享它。 (另外,我包括 "withCredentials" 标志)
这是初始调用的代码(并设置后续调用):
$.ajax({url: 'https://api.domain.com/get-cookie',
xhrFields: {
withCredentials: true
}
})
.done(function (response) {
$('.selectpicker').selectpicker().ajaxSelectPicker({
ajax: {
// data source
url: 'https://api.domain.com/data.json',
// ajax type
type: 'GET',
// data type
dataType: 'json',
// Use "{{{q}}}" as a placeholder and Ajax Bootstrap Select will
// automatically replace it with the value of the search query.
data: {
q: '{{{q}}}'
}
},
// function to preprocess JSON data
preprocessData: function (data) {
var i, l = data.length, array = [];
if (l) {
for (i = 0; i < l; i++) {
array.push($.extend(true, data[i], {
text : data[i].name,
value: data[i].code,
data : {
subtext: data[i].code
}
}));
localStorage.setItem(data[i].code, data[i].name);
}
}
// You must always return a valid array when processing data. The
// data argument passed is a clone and cannot be modified directly.
return array;
}
});
}
);
我正在使用 AWS API 网关和 Lambda 函数,但这应该不相关...
从 selectPicker(例如:https://api.domain.com/data.json )获取 url 并将其直接放入浏览器时,我看到正在发送 cookie。 这似乎表明问题可能出在未正确发送 headers 的 Bootstrap Select 组件中。 我不确定我是否可以让它按预期工作,或者我必须找到其他替代方案。
解决方案是在选择器请求中也包含 withCredentials:
$('.selectpicker').selectpicker().ajaxSelectPicker({
ajax: {
// data source
url: 'https://api.domain.com/data.json',
// ajax type
type: 'GET',
// data type
dataType: 'json',
// Use "{{{q}}}" as a placeholder and Ajax Bootstrap Select will
// automatically replace it with the value of the search query.
data: {
q: '{{{q}}}'
},
xhrFields: {
withCredentials: true
}
},
// function to preprocess JSON data
preprocessData: function (data) {
// ...
}
});
}
);
感谢@CBroe 在评论中提出的想法。