跨域

142 阅读4分钟

简介

跨域(Cross-Origin)是指在浏览器中,当一个网站的文档(或脚本、图像等资源)要访问另一个网站的资源时,如果这两个网站的 协议端口域名 任意一个不同,就会发生跨域问题。跨域问题的存在是因为浏览器出于安全考虑,限制了不同源之间的通信,防止恶意网站窃取用户信息。常见的跨域场景包括 AJAX 跨域请求、跨域图片资源加载、iframe 跨域嵌套等。

也就是说,浏览器出于安全考虑,针对浏览器环境使用了同源策略,是不允许跨域的。

同源策略

同源策略(Same-Origin Policy)是 浏览器中常用的一种安全策略。同源策略规定了浏览器中的 JavaScript 脚本只能与加载它的 HTML 页面具有相同的协议、主机名和端口号,才能访问对方页面的资源或与页面交互。同源策略主要是为了防止恶意网站使用用户浏览器的安全漏洞,窃取用户信息或进行 CSRF(跨站请求伪造)等攻击。

需要注意的是,同源策略只是针对浏览器环境有效,因此不会影响服务器之间的交互通信。通常在实际开发中,我们通过 JSONP、CORS 等技术手段来实现浏览器跨域请求的功能。

    • window.originlocation.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
  • 缺点:
  1. 由于是script标签,它读不到AJAX那么精确的状态。不知道状态码和响应头是什么,只知道成功或失败了
  2. 由于是script标签,只能发GET请求。不支持POST

代码示例:coolkechang/kuayu-CORSandJSONP (github.com)


资料来源:饥人谷前端课程