We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
总结一下这篇文章的大概内容?
浏览器为了保证用户信息安全,所有的浏览器都遵循同源策略。
现在大部分网站登录后,都会在浏览器 cookie 存一个标识,标识这个用户。 如果没有同源策略,我自己做一个页面,然后随便去拿其他网站的 cookie,然后伪装成这个用户,做一些恶意操作(发布不良消息,提现,删除好友,七七八八的), 这样就很不安全了。
协议、域名、端口号完全相同时,才是同源
cookie,local storage ,indexDB 无法读取
DOM 无法获取
Ajax 请求无法获取
浏览器会发送请求,服务端也会收到请求,并处理完成返回数据,只是返回后,浏览器发现请求头并没有说明这个接口允许该域名去请求,因此给拦截掉,并报错。【Chrome 浏览器的机制是这样的】
解决跨域的方法有很多,但是最常用的是现在的 CROS, 和早期的 JSONP。
CROS 【下文会详细讲】
JSONP
利用 html 中,script 资源请求不存在跨域的问题,然后去做接口请求。然后把数据放在回调函数的参数内。
CORS跨域的原理实际上是浏览器与服务器通过一些HTTP协议头来做一些约定和限制。可以查看 HTTP访问控制(CORS)
与跨域相关的协议头
Chrome 浏览器跨域的报错是这样的,见下图
跨域请求,并不是浏览器没有发出请求,而是浏览器发出请求了,服务端也返回了数据,但是返回到浏览器后,被浏览器拦截了。【Chrome 浏览器下是如此】
通过设置响应头,告诉浏览器,该资源可以吐给指定的 origin。
Access-Control-Allow-Origin 响应头指定了该响应的资源是否被允许与给定的origin共享。
Access-Control-Allow-Origin
// 加上允许跨域请求的地址 res.setHeader("Access-Control-Allow-Origin", "http://192.168.10.8:8080");
简单请求,只需要设置了 Access-Control-Allow-Origin 即可完成跨域请求。
那么什么是简单请求呢?
GET / HEAD
POST 并且Content-Type的值在下列之一:
- text/plain - multipart/form-data - application/x-www-form-urlencoded
并且请求头中只有下面这些
- Accept - Accept-Language - Content-Language - Content-Type (需要注意额外的限制) - DPR - Downlink - Save-Data - Viewport-Width - Width
content-type: "application/json" 这个就不是简单请求了。
预检请求就是先发一个请求到服务端,问我发一个非常规请求,你可以处理吗?
这个预检请求的作用在这里就是告诉服务器:我会在后面请求的请求头中以POST方法发送数据类型是application/json的请求,询问服务器是否允许。
服务端如何没有做任何处理的时候,会报这个错误。
// 这个时候只要在响应头添加一个 Access-Control-Allow-Headers = content-type 即可 res.setHeader("Access-Control-Allow-Headers", "Content-Type");
有个问题,做预检请求的时候,浏览器会发出两个同样地址请求,一个 OPTIONS 和 一个 POST 的请求。
预检请求发送到服务端,如果没有处理的请求下,服务端还是会去走一整套的流程,从数据库那数据,处理,在返回。
如何避免服务端做重复处理呢?
case "/api/post": // 这边处理一下,避免服务端做两次逻辑处理 if (req.method === "OPTIONS") { res.end("true"); } else { res.end( JSON.stringify({ data: { name: "zhongxia" }, success: true }) ); } break;
经过观察发现,跨域请求,并不会带上 cookie
注意,这里的 cookie,并不是这个跨域的这个域名,而是会带上接口的那个域名。 服务端写入 cookie,也是写到 接口的那个域名下。
注意,这里的 cookie,并不是这个跨域的这个域名,而是会带上接口的那个域名。
服务端写入 cookie,也是写到 接口的那个域名下。
服务端写入 cookie,也没用写到 跨域的那个域名下。
// 允许跨域的接口请求,往自己域名写入 cookie res.setHeader("Access-Control-Allow-Credentials", "true");
$.ajax({ method: "POST", url: "http://127.0.0.1:8888/api/post", xhrFields: { withCredentials: true // 加上这个,发送请求,就能带上接口域名下的 cookie }, headers: { "Content-Type": "application/json" //告诉服务器实际发送的数据类型 }, error: err => { console.log(err); }, success: data => { $("#result1").html(JSON.stringify(data, null, 2)); } });
当前域名是 : 127.0.0.1:8888 , 请求的接口域名是:192.168.10.8:8080 , 存在跨域 跨域请求带上的 cookie,是接口域名的 cookie。
当前域名是 : 127.0.0.1:8888 , 请求的接口域名是:192.168.10.8:8080 , 存在跨域
跨域请求带上的 cookie,是接口域名的 cookie。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
CROS 跨域问题详解
总结一下这篇文章的大概内容?
一、为什么会有跨域问题?
现在大部分网站登录后,都会在浏览器 cookie 存一个标识,标识这个用户。 如果没有同源策略,我自己做一个页面,然后随便去拿其他网站的 cookie,然后伪装成这个用户,做一些恶意操作(发布不良消息,提现,删除好友,七七八八的), 这样就很不安全了。
1.1、同源策略是什么?
1.2、同源策略限制了哪些内容?
cookie,local storage ,indexDB 无法读取
DOM 无法获取
Ajax 请求无法获取
浏览器会发送请求,服务端也会收到请求,并处理完成返回数据,只是返回后,浏览器发现请求头并没有说明这个接口允许该域名去请求,因此给拦截掉,并报错。【Chrome 浏览器的机制是这样的】
二、如何解决跨域问题?
解决跨域的方法有很多,但是最常用的是现在的 CROS, 和早期的 JSONP。
CROS 【下文会详细讲】
JSONP
利用 html 中,script 资源请求不存在跨域的问题,然后去做接口请求。然后把数据放在回调函数的参数内。
2.1、CROS 的跨域原理
CORS跨域的原理实际上是浏览器与服务器通过一些HTTP协议头来做一些约定和限制。可以查看 HTTP访问控制(CORS)
与跨域相关的协议头
三、CROS 为什么能解决跨域
Chrome 浏览器跨域的报错是这样的,见下图
3.1、为什么设置了 CROS 可以跨域呢?
跨域请求,并不是浏览器没有发出请求,而是浏览器发出请求了,服务端也返回了数据,但是返回到浏览器后,被浏览器拦截了。【Chrome 浏览器下是如此】
通过设置响应头,告诉浏览器,该资源可以吐给指定的 origin。
Access-Control-Allow-Origin
响应头指定了该响应的资源是否被允许与给定的origin共享。3.2、简单请求和预检请求
简单请求,只需要设置了
Access-Control-Allow-Origin
即可完成跨域请求。那么什么是简单请求呢?
GET / HEAD
POST 并且Content-Type的值在下列之一:
并且请求头中只有下面这些
3.3、预检请求有什么不一样?
预检请求就是先发一个请求到服务端,问我发一个非常规请求,你可以处理吗?
这个预检请求的作用在这里就是告诉服务器:我会在后面请求的请求头中以POST方法发送数据类型是application/json的请求,询问服务器是否允许。
服务端如何没有做任何处理的时候,会报这个错误。
有个问题,做预检请求的时候,浏览器会发出两个同样地址请求,一个 OPTIONS 和 一个 POST 的请求。
预检请求发送到服务端,如果没有处理的请求下,服务端还是会去走一整套的流程,从数据库那数据,处理,在返回。
如何避免服务端做重复处理呢?
四、带凭证信息的请求
经过观察发现,跨域请求,并不会带上 cookie
服务端写入 cookie,也没用写到 跨域的那个域名下。
4.1、 如何让服务端接口能写入 cookie
4.2、如何让客户端发起请求,能带上 cookie
参考文档
The text was updated successfully, but these errors were encountered: