未通过api调用跨子域请求发送Cookie

时间:2020-04-16 12:58:54

标签: javascript jquery ajax cookies bootstrap-select

我的页面存储在https://page.domain.com上。 在这里,我正在使用javascript(主要是Bootstrap)从https://api.domain.com获取数据。 加载页面时,第一个调用是“某种”身份验证调用,它将在标头中返回cookie:

set-cookie: oauth=emd4YWgybTJobmJnZjVrbXl2ZjdlZThiOzkzczg1YWt2YzNyZW42cjk3M2U4dXlweA==; domain=.domain.com; path=/; expires=Fri, 16 Apr 2021 11:58:07 GMT;

我可以在开发人员工具(Chrome)中看到Cookie的存储正确。

但是,当我进行下一个api调用时(例如,填写下拉列表-bootstrap autocomplete),cookie不在请求中。 当我在localhost(我想是相同的“域”)中构建它时,它运行良好,但是现在,由于html和api在不同的域上运行,因此似乎未共享cookie。 我以为可能是因为两个不同的域,但是根据文档,当cookie设置为主域时,所有子域都应该能够共享它。 (而且,我包括“ 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 Gateway和Lambda函数,但这应该不相关...


当从selectPicker获取网址(例如:https://api.domain.com/data.json)并将其直接放在浏览器中时,我看到正在发送cookie。 这似乎表明问题可能出在Bootstrap Select组件中,该组件未正确发送标头。 我不确定是否可以使它按预期工作,还是必须找到其他替代方法。

1 个答案:

答案 0 :(得分:0)

解决方案是在选择器请求上还包括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。