<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <blockquote>
讯享网
实现跨域请求,我们首先要先知道什么是跨域,紧接着便是跨域的方法,最后则是跨域时cookie的处理。
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制内容有:
但是有三个标签是允许跨域加载资源:
当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。
特别说明两点:
- 第一:如果是协议和端口造成的跨域问题“前台”是无能为力的。
- 第二:在跨域问题上,仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”。
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。
CORS 通信过程都是浏览器自动完成,需要浏览器(都支持)和服务器都支持,所以关键在只要服务器支持,就可以跨域通信,CORS请求分两类,简单请求和非简单请求
另外CORS请求默认不包含Cookie以及HTTP认证信息,如果需要包含Cookie,需要满足几个条件:
- 服务器指定了 Access-Control-Allow-Credentials: true
- 开发者须在请求中打开withCredentials属性: xhr.withCredentials = true
- Access-Control-Allow-Origin 不要设为星号,指定明确的与请求网页一致的域名,这样就不会把其他域名的Cookie上传
简单请求
需要同时满足两个条件,就属于简单请求:
- 请求方法是:HEAD、GET、POST,三者之一
- 请求头信息不超过以下几个字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-Id
- Content-Type:值为三者之一application/x-www/form/urlencoded、multipart/form-data、text/plain
需要这些条件是为了兼容表单,因为历史上表单一直可以跨域
浏览器直接发出CORS请求,具体来说就是在头信息中增加Origin字段,表示请求来源来自哪个域(协议+域名+端口),服务器根据这个值决定是否同意请求。如果同意,返回的响应会多出以下响应头信息
讯享网
在这个示例中,我们使用了 XMLHttpRequest 对象来进行跨域请求。我们设置了 withCredentials 属性为 true,表示允许跨域请求。同时,在服务器响应中需要设置以上响应头,其中 Access-Control-Allow-Origin 表示允许哪个域名下的请求,Access-Control-Allow-Credentials 表示是否允许发送凭证(如 cookie、HTTP 认证等)。
非简单请求
比如 PUT 或 DELETE 请求,或 Content-Type 为 application/json ,就是非简单请求。
非简单 CORS 请求,正式请求前会发一次 OPTIONS 类型的查询请求,称为预检请求,询问服务器是否支持网页所在域名的请求,以及可以使用哪些头信息字段。只有收到肯定的答复,才会发起正式XMLHttpRequest请求,否则报错
预检请求的方法是OPTIONS,它的头信息中有几个字段
- Origin: 表示请求来自哪个域,这个字段是必须的
- Access-Control-Request-Method:列出CORS请求会用到哪些HTTP方法,这个字段是必须的
- Access-Control-Request-Headers: 指定CORS请求会额外发送的头信息字段,用逗号隔开
OPTIONS请求次数过多也会损耗性能,所以要尽量减少OPTIONS请求,可以让服务器在请求返回头部添加
讯享网
JSONP 是一种常见的跨域请求方法。它是通过在 HTML 页面中添加一个 script 标签,来请求一个位于其他域名下的 JavaScript 文件。该 JavaScript 文件返回的数据需要使用一个回调函数进行包装,以便在原始页面中可以接收到数据。
在这个示例中,我们通过添加一个 script 标签来请求 http://example.com/data.json 这个地址下的数据。由于该地址存在跨域问题,我们指定了一个名为 jsonpCallback 的回调函数,并将回调函数名作为参数传递到了地址中。当服务器返回数据时,会自动调用回调函数并将数据作为参数传入。
如果无法使用 JSONP 或 CORS,可以尝试使用代理服务器来转发请求。在前端中,可以向自己的服务器发送请求,然后让服务器代理请求其它域名下的资源,并将结果返回给前端。
讯享网
在这个示例中,我们向自己的服务器发送了一个 GET 请求,并在请求地址中添加了一个名为 proxy 的参数。服务器接收到请求后会将该请求转发到 http://example.com/data.json 地址下,并将响应结果返回给前端。
WebSocket 是一种支持跨域请求的协议,它允许客户端和服务器之间建立一个双向的通信通道。通过 WebSocket 可以实现跨域传输数据。
因为WebSocket请求头信息中有Origin字段,表示请求源来自哪个域,服务器可以根据这个字段判断是否允许本次通信,如果在白名单内,就可以通信
客户端代码:
在这个示例中,我们通过创建一个 WebSocket 对象来连接 ws://example.com/ws 这个地址下的 WebSocket 服务。当连接建立成功后,我们发送了一段消息给服务器。当服务器返回消息时,会自动触发 onmessage 事件,并将服务器发送的数据作为参数传入。
需要注意的是,在使用 WebSocket 进行跨域通信时,服务器必须显式地指定允许哪些源访问 WebSocket 服务。服务器需要在握手阶段返回一个 Upgrade 头部,并在该头部中指定 Origin 头部的值。以下是一个使用 Node.js 实现的 WebSocket 服务的示例代码:
讯享网
在这个示例中,我们使用了 ws 模块创建了一个 WebSocket 服务,并监听在 8080 端口上。当客户端连接成功后,会触发 connection 事件,并返回一个 WebSocket 对象 ws。当客户端发送消息时,会自动触发 message 事件,并将客户端发送的数据作为参数传入。在这个示例中,我们将收到的消息直接返回给客户端。

postMessage 是一种在不同窗口或跨域框架之间进行通信的机制。它允许一个窗口向另一个窗口发送消息,无论这两个窗口是否同源。
使用 postMessage 进行通信时,需要提供目标窗口的引用,并通过调用 postMessage 方法发送消息。以下是一个示例:
在这个示例中,首先获取了目标窗口的引用 targetWindow,然后通过调用 postMessage 方法向目标窗口发送消息。发送的消息可以是任意类型的数据,例如字符串、对象等。
在接收消息的窗口中,通过添加 message 事件监听器来监听消息的接收,然后通过 event.data 获取收到的消息内容。可以通过 event.origin 来验证消息来源的域,确保只接受来自指定域的消息。
需要注意的是,为了确保安全性,应该始终在 postMessage 中指定目标窗口的源,以防止恶意窗口的干扰。同时,在接收消息时,应该对消息来源进行验证,并仅处理来自可信任源的消息。
总结来说,postMessage 提供了一种安全的跨窗口通信机制,可以在不同窗口、跨域框架之间进行双向通信。
这里只介绍几种开发中用的比较多的,几乎用不到的比如:
- :适用主域名相同,子域名不同的跨域场景
- :利用name值最长可以 2M ,并用不同页面或不同域名加载后依然存在的特性
- :适用通过 C 页面来实现 A 页面与 B 页面通信的场景
在跨域请求中,Cookie 的处理需要额外注意。默认情况下,跨域请求是不会携带 Cookie 的,这是出于安全考虑。
如果你想在跨域请求中携带 Cookie,有以下几种方法:
- :在服务端设置响应头部,允许指定的源携带 Cookie。具体做法是,在服务器返回的响应头中添加 Access-Control-Allow-Credentials: true,表示允许携带凭证(如 Cookie);同时,需要指定允许访问的源,可以使用 Access-Control-Allow-Origin: http://yourdomain.com 来限制只允许特定域名的请求携带 Cookie。
- :将跨域请求发送到自己的服务器上,然后再由自己的服务器转发请求,并将响应返回给前端。由于请求是在同源下发起的,因此可以携带 Cookie。前端将请求发送给自己的服务器,然后自己的服务器再将请求发送给目标服务器,并将目标服务器的响应返回给前端。
- :可以将需要的信息以参数的形式附加在 URL 上,而不是通过 Cookie 传递。这样不会触发同源策略,也不会引起跨域问题。
需要注意的是,使用 Cookie 进行跨域请求时,还需要设置 XMLHttpRequest 对象的 withCredentials 属性为 true。例如:
讯享网
同时,在服务端也要对跨域请求进行相应的处理,以确保安全性。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/197927.html