【笔记】跨域重定向中使用Ajax(XHR请求)导致跨域失败

背景:

1、前端Web中有两个域名,a.com和b.com,其中a.com是访问主站(页面),b.com是数据提交接口的服务器(XHR请求)

2、a.com中用XHR调用b.com/cerate【没有指定协议】,保存数据,写法如下:

$.ajax({url: "//b.com/create",type: 'POST',data: requestParams,dataType: 'json',xhrFields: {withCredentials: true},crossDomain: true,async: false,success: function (data) {// ...},error: function (ret) {// ...
});

  

3、线上环境中,a.com和b.com的都在Nginx中配置了302强制跳转https

4、某个测试环境中,a.com没有跳转https,b.com有

 

问题:

1、线上环境,用户访问的是https://a.com,调用接口为https://b.com/create,跨域没有问题。

2、但是在测试环境中,测试人员直接打开了http://a.com页面,调用接口就变成为http://b.com/create,这里跨域预检时,b.com的Nginx反馈302跳转,报错。

{"readyState":0,"status":0,"statusText":"NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://b.com/create."}

 

分析:

1、readtState: 0说明请求没有发出去,被浏览器拦截了,可能情况有:

  • url格式不对
  • 跨域失败
  • 参数错误
  • 用户取消
  • 其它...

2、这里应该是跨域失败的问题,因为报错是faild to load url

3、之前没有关注过跨域重定向问题,StackOverFlow之:

https://stackoverflow.com/questions/18539403/chrome-cancels-cors-xhr-upon-http-302-redirect/38810391#38810391

4、W3C标准 https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0

5、总的来说,就是对于非简单请求(XHR等),当跨域预检(Option请求)时,如果出现非20X等时,会直接失败,抛出readtState: 0

 

解决方法:

1、在Ajax中明确https协议,避免b.com预检时返回302

$.ajax({url: "https://b.com/create",type: 'POST',data: requestParams,dataType: 'json',xhrFields: {withCredentials: true},crossDomain: true,async: false,success: function (data) {// ...},error: function (ret) {// ...
});

  

2、修改测试环境a.com下的服务器,保持和线上环境一致,不让用户走到http://a.com,强制走https://a.com访问页面

 

总结:

之前一直觉得:

请求中不指定协议,使用//自动适配页面url的协议

是一个标准规范。现在看来,对于简单请求,比如页面跳转、图片加载等确实是一个好的做法,但是对于后端接口请求这类,可能需要具体场景斟酌。这句话可以改为:

简单请求中不指定协议,使用//自动适配页面url的协议

转载于:https://www.cnblogs.com/smileSmith/p/9277060.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript --- js中prototype、__proto__、[[Propto]]、constructor的关系

首先看下面一行代码: function Person(name){this.name name; } var person1 new Person; console.log(person1.__proto__ Person.prototype); console.log(person1.constructor Person);控制台打印如下: 可以看见,当使用构造函数(Person)构造一个实例(person1)时, 在后…

前端知识点整理收集(不定时更新~)

知识点都是搜集各种大佬们的,如有冒犯,请告知! 目录 原型链 New关键字的执行过程 ES6——class constructor方法 类的实例对象 不存在变量提升 super 关键字 ES6——...(展开/收集)运算符 面向对象的理解 关…

数据库四大特性与隔离级别

数据库四大特性ACID Atomicity (原子性) :事务(transaction)是由指逻辑上对数据的的一组操作,这组操作要么一次全部成功,如果这组操作全部失败,是不可分割的一个工作单位。 Consistency(一致性) :在事务开始以前&#…

重学《JavaScript 高级程序设计》笔记 第6章对象

第6章 面向对象的程序设计 ECMAScript中没有类的概念; 1.创建对象-历史 1.1 创建实例,添加方法和属性 → 对象字面量 缺点: 使用同一接口创建很多对象,产生大量重复代码 var person new Object() person.name "Y" pe…

Java-reflect(反射)初步理解_1

27.01_反射(类的加载概述和加载时机) A:类的加载概述 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。加载 就是指将class文件读入内存,并为之创建一个…

javascrip --- 构造函数的继承

两点需要注意的. 第一是在构造函数声明时,会同时创建一个该构造函数的原型对象,而该原型对象是继承自Object的原型对象 // 声明一个构造函数Rectengle function Rectangle(length, width) {this.length length;this.width width; }// 即:看见function 后面函数名是大写,一般…

Ruby实例方法和类方法的简写

创建: 2017/12/12 类方法 Sample.func实例方法 Sample#func转载于:https://www.cnblogs.com/lancgg/p/8281677.html

《JavaScript 高级程序设计》笔记 第7章及以后

第7章 函数表达式 匿名函数的name属性是空字符串;闭包是函数:闭包是有权访问另一个函数作用域中变量的函数;(P181 副作用,解释了点击li弹出循环最后值的原因)当某个函数第一次被调用时,会创建一个执行环境及相应作用域链&#xf…

[树形dp] Jzoj P1046 寻宝之旅

Description 探险队长凯因意外的弄到了一份黑暗森林的藏宝图,于是,探险队一行人便踏上了寻宝之旅,去寻找传说中的宝藏。藏宝点分布在黑暗森林的各处,每个点有一个值,表示藏宝的价值。它们之间由一些小路相连&#xff0…

javascript --- 使用语法糖class定义函数

本文讨论的是通过class声明的函数,有什么特点,或者说是指向了哪里. class A() {} // A是一个类// 要看class声明的函数指向哪里,只需将其[[Prototype]]属性打印到控制台,下面看看A和它的原型对象的指向 // 注:[[Prototype]]属性通过__proto__访问 console.log(A.__proto__…

前端知识点整理收集(不定时更新~)二

目录 require() 加载文件机制 线程和进程 线程 单线程 Nodejs的线程与进程 网络模型 初识 TCP 协议 三次握手 I/O I/O 先修知识 阻塞与非阻塞 I/O 同步与异步 I/O Git 基础命令 分支操作 修改远程仓库地址 远程分支获取最新的版本到本地 拉取远程仓库指定分支…

SpringBoot零基础入门指南--搭建Springboot然后能够在浏览器返回数据

File->new Project 修改默认包名,根据自己的喜好修改 选择初始化需要导入的包,尽量不要一开始就导入很多,特别是数据库,不然启动可能会有问题,创建好的目录如下: 配置文件写在application.properties下&…

JavaScript算法相关

1. 排序 1.1.冒泡排序 每一轮比较&#xff0c;从左至右交换相邻&#xff0c;每轮结束&#xff0c;最后一个为最大下一轮&#xff0c;需要比较的个数 - 1 j < len - i (范围动态缩小)共 len - 1 轮比较 function bubbleSort(arr) {var len arr.length;for (var i 1; i &…

javascript --- 编程风格

字符串 const a foobar; const b foo${a}bar; // 此处是反引号(tab键上) const c foobar;解构赋值 const [first, second] arr;function getFullName({ firstName, lastName }) { }function processInput(input) {return { left, right, top, bottom }; } const { left…

$ - 字符串内插

$ 特殊字符将字符串文本标识为内插字符串。 内插字符串是可能包含内插表达式的字符串文本。 将内插字符串解析为结果字符串时&#xff0c;带有内插表达式的项会替换为表达式结果的字符串表示形式。 此功能在 C# 6 及该语言的更高版本中可用。 与使用字符串复合格式设置功能创建…

数据结构基础知识

排序 参考&#xff1a;https://www.bilibili.com/video/av38482633/?spm_id_fromtrigger_reload 目录 排序 插入排序 直接插入排序 折半排序 希尔排序 ​ 交换排序 冒泡排序 快速排序 选择排序 堆排序 流量单位计算 什么是计数排序 复杂度分析&#xff1a; 什…

linux中安装软件,查看、卸载已安装软件方法

各种主流Linux发行版都采用了某种形式的包管理系统&#xff08;PMS&#xff09;来控制软件和库的安装。 软件包存储在服务器上&#xff0c;可以利用本地Linux系统上的PMS工具通过互联网访问。这些服务器称为仓库。 由于Linux发行版众多,目前还没有统一的PMS标准工具。 这里分别…

html5 --- 使用javascript脚本控制媒体播放

H5中的标签(<audio…/> 和 <video…/>)对于JS中的HTMLAudioElement对象和HTMLVideoElement对象 对象有以下几个方法: play(): 播放 pause(): 暂停播放 load(): 重新装载音频、视频 canPlayType(type): 判断该元素可播放type类型的音频、视频 下面是一个简单的音乐…

在js中if条件为null/undefined/0/NaN/表达式时,统统被解释为false,此外均为true

Boolean 表达式 一个值为 true 或者 false 的表达式。如果需要&#xff0c;非 Boolean 表达式也可以被转换为 Boolean 值&#xff0c;但是要遵循下列规则&#xff1a; 所有的对象都被当作 true。当且仅当字符串为空时&#xff0c;该字符串被当作 false。null 和 undefined 被当…

ES6专题——整理自阮一峰老师的ECMAScript 6入门

这里我仅仅是记录了那些我认为值得注意的ES6知识点&#xff0c;详细版请挪步https://es6.ruanyifeng.com/#docs/let let和const命令 let声明的变量只在它所在的代码块有效。 var a []; for (let i 0; i < 10; i) {a[i] function () {console.log(i);}; } a[6](); // 6 …