简介
跨域(Cross-Origin)是指在浏览器中,当一个网站的文档(或脚本、图像等资源)要访问另一个网站的资源时,如果这两个网站的 协议、 端口 或 域名 任意一个不同,就会发生跨域问题。跨域问题的存在是因为浏览器出于安全考虑,限制了不同源之间的通信,防止恶意网站窃取用户信息。常见的跨域场景包括 AJAX 跨域请求、跨域图片资源加载、iframe 跨域嵌套等。
也就是说,浏览器出于安全考虑,针对浏览器环境使用了同源策略,是不允许跨域的。
同源策略
同源策略(Same-Origin Policy)是 浏览器中常用的一种安全策略。同源策略规定了浏览器中的 JavaScript 脚本只能与加载它的 HTML 页面具有相同的协议、主机名和端口号,才能访问对方页面的资源或与页面交互。同源策略主要是为了防止恶意网站使用用户浏览器的安全漏洞,窃取用户信息或进行 CSRF(跨站请求伪造)等攻击。
需要注意的是,同源策略只是针对浏览器环境有效,因此不会影响服务器之间的交互通信。通常在实际开发中,我们通过 JSONP、CORS 等技术手段来实现浏览器跨域请求的功能。
- 源
window.origin或location.origin可以得到当前源- 源 = 协议 + 域名 + 端口号
- 如果两个 url 的 协议、域名、端口号 完全一致,那么这两个 url 就是同源的
跨域的方法
浏览器默认不同源之间不能互相访问数据。如果要共享数据,需要提前声明!
- 实现跨域的方法
- CORS(Cross-Origin Resource Sharing):允许服务器在响应头中设置 Access-Control-Allow-Origin 等相关字段,客户端通过预检请求(OPTIONS)获取授权后,可以在浏览器中进行跨域访问。
- JSONP:通过动态创建 script 标签,向服务器请求数据并手动处理响应数据,不受同源策略限制,但只能使用 GET 方法。
- 代理:在客户端的代码里,请求同域下的服务器,读取服务器数据,然后将数据返回客户端,从而绕过跨域限制。
- WebSocket:由于 WebSocket 是基于 HTTP 协议实现的,可以使用握手协议协商跨域权限,实现跨域通信。
- postMessage:通过在 iframe 或者新窗口里通过 postMessage 标准接口来实现跨域消息传递。
CORS
CORS,(跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。
语法:
服务器响应头添加
response.setHeader(
'Access-Control-Allow-Origin',
'http://chang.com'
)
这表示服务器允许http://chang.com进行跨域访问。这样在请求方可以发送访问请求,例如:
const request = new XMLHttpRequest()
request.open('get', 'http://qq.com:8888/friends.json')
request.onreadystatechange = () => {
if (request.readyState === 4 && request.status === 200) {
console.log(request.response)
}
}
request.send()
JSONP
JSONP (JSON with Padding) 是一种跨域请求技术,它通过动态创建 script 元素,向服务器发起 GET 请求,并指定一个回调函数作为参数。服务器收到请求后,将数据包装在回调函数中返回,即返回一个 JavaScript 函数调用,浏览器接收到响应后,直接执行响应内容,回调函数的参数就是服务器返回的数据。
由于 JSONP 不受同源限制,因此可以实现跨域请求。同时, JSONP 可以通过 URL 参数的形式传递数据,从而支持跨域数据传输。
使用 JSONP 需要服务端支持,需要在服务端处理请求并返回包含响应数据或错误信息的 JavaScript 函数调用。同时,在客户端要定义一个回调函数,它的参数即为服务器返回的数据,该回调函数名需要传递给服务器,并在响应数据中包含。
JSONP 技术的缺点是只支持 GET 方法,数据不够安全,容易遭受 CSRF 攻击,因此在实际开发中,应该使用更加安全的方式,如 CORS。
JSONP 问答
- JSONP是什么?
- JSONP是我们在进行跨域时当前浏览器不支持CORS所使用的另一种方法。
- 用JSONP创建一个script(标签)去请求另一个网站的JS文件,这个JS文件执行一个回调,回调里有我们要的数据,这些数据会在我的网站上调用一个全局函数运行。
- 回调的名字是什么?
- 这回调的名字是可以随机生成的一个随机数,我们用callback这个参数传给后台,后台会把这个参数返回给我们并执行。
- 优点:
- 可以跨域
- 支持IE
- 缺点:
- 由于是script标签,它读不到AJAX那么精确的状态。不知道状态码和响应头是什么,只知道成功或失败了
- 由于是script标签,只能发GET请求。不支持POST
代码示例:coolkechang/kuayu-CORSandJSONP (github.com)
资料来源:饥人谷前端课程