美文网首页我爱编程
跨域解决方案

跨域解决方案

作者: 咕嘟咕嘟li | 来源:发表于2018-04-14 13:34 被阅读39次

举例URL: https://www.stuspy.com/mxsj/paperTest.html?id=5a56d694ac502e0042d73dce

  • 协议部分:https:
  • 分隔符: //
  • 域名部分:www.stuspy.com
  • 端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
  • 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“paperTest.html”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  • 锚部分:从“#”开始到最后,都是锚部分。锚部分也不是一个URL必须的部分
  • 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分,本例的虚拟目录为“/mxsj/”
    参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。本例中的参数部分为“id=5a56d694ac502e0042d73dce”
    概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。

跨域的几种情况

  • 协议不同
  • 域名相同,端口不同
  • 域名与域名对应ip
  • 域名不同
  • 主域相同,子域不同
  • 同一域名,不同二级域名

跨域解决方案

1.CORS(主要解决的是异域之间的传值)

跨源资源共享定义了在必须访问跨源资源时,浏览器与服务器该如何沟通。其背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是否应该成功。

  • 对于客户端,我们还是正常使用xhr对象发送ajax请求。
  • 对于服务器端,需要在 response header中设置Access-Control-Allow-Origin字段。
    IE8 通过 XDomainRequest 对象支持CORS,其他浏览器通过 XHR 对象原生支持 CORS。

2.图像Ping

图像Ping——最常用于跟踪用户点击页面或动态广告曝光次数。有两个主要的缺点,一是只能发送GET请求,二是无法访问服务器的响应文本。因此,图像Ping只能用于浏览器与服务器间的单向通信。

3.JSONP

JSONP(JSON with padding的简写)——是一种基于文本的数据交换方式,或者叫做数据描述格式。jsonp通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL,因为 JSONP 是有效的 JavaScript 代码,所以在请求完成后,即在 JSONP 响应加载到页面中以后,就会立即执行。

JSONP的优点:

在于能够直接访问响应文本,支持在浏览器与服务器之间双向通信。

JSONP的不足:
  • 首先,JSONP 是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃 JSONP 调用之外,没有办法追究。因此在使用不是你自己运维的 Web 服务时,一定得保证它安全可靠。
  • 其次,要确定 JSONP 请求是否失败并不容易。

4.window.postMessage()

window.postMessage()方法被调用时,会在所有页面脚本执行完毕之后,向目标窗口派发一个 MessageEvent消息。

message 的属性有:
data:从其他 window 中传递过来的对象。
origin:调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置
source:对发送消息的窗口对象的引用; 可以使用它来在具有不同origin的两个窗口之间建立双向通信。

window.postMessage()安全问题
  1. 如果不希望从其他网站接收message,就不要为message事件添加任何事件侦听器
  2. 始终使用origin和source属性验证发件人的身份
// 消息发送方
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请求页面</title>
</head>
<body>
<div>
    <p>这里是2000端口</p>
    <input type="text"/>
    <button>发送信息</button>
    <p style="text-align: left;">message :  <span></span></p>
</div>
<iframe  id="child" src="http://localhost:2001"></iframe>
<script>
    var input = document.getElementsByTagName('input')[0];
    var btn = document.getElementsByTagName('button')[0];
    var frame = document.getElementById('child').contentWindow;
    btn.onclick = function () {
      var msg = input.value;
      frame.postMessage('收到信息:' + msg + ' --from 2000 port!', 'http://localhost:2001');
    }
</script>
</body>
</html>
// 消息接收方
// 注册message事件并绑定事件监听函数
if (window.addEventListener) { 
  window.addEventListener('message', receiveMessage, false);
 } else {
   window.attachEvent('message', receiveMessage);
}
function receiveMessage(event) {
  // For Chrome, the origin property is in the event.originalEvent
  var origin = event.origin || event.originalEvent.origin; 

  // 使用origin或source属性验证发件人的身份
  if (origin !== "http://localhost:2000") { // http://localhost:2000为自己定义的地址
    return;
  }

  // Do Something ...
  var data = event.data;
  console.log(data)
}

该跨域方法适合于同一页面的不同窗体(iframe)

5.document.domain(主要解决的是子域与父域之间的传值)

  • 定义:domain 属性可返回下载当前文档的服务器域名。
  • 局限性: 一级域名一致才可以使用document.domain进行跨域访问
    • 注:一级域名又称顶级域名。一级域名中只含有一个“.”,且“.”左边要有内容,最后一个点的右边被称为一级域名,左边被称为二级域名,以此类推二级三级域名。

现有父域:http://b.com/b.com.html
要向子域:http://a.b.com/a.b.com.html获取数据
两个域都设置如下:

 document.domain = 'b.com'; //设置成主域

这样就解决了子域与父域间的跨域问题

6. 后端设置代理proxy跨域

var express = require('express');
var proxy = require('http-proxy-middleware');

var requestPort = 2000; 
var app = express();

app.use(express.static(__dirname));

app.use('/api', proxy({target: 'http://localhost:2001/', changeOrigin: true}));
// changeOrigin设置为true,本地会虚拟一个服务端接收你的请求并代你发送该请求
// http://localhost:2000/api   -->   http://localhost:2001/api

app.listen(requestPort, function () {
    console.log('Requester is listening on port '+ requestPort);
});

7.WebSocket跨域

Web Sockets 是一种与服务器进行全双工、双向通信的信道。与其他方案不同,Web Sockets 不使用HTTP 协议,而使用一种自定义的协议——WebSocket 通信

相关文章

  • Web前后端跨域问题处理

    跨域问题有前台跨域(iframe间)和后台跨域。 前台跨域的解决方案可以采用跨域文档通讯(Cross domain...

  • 跨域问题,解决方案

    跨域问题,解决方案 - Nginx反向代理跨域问题,解决方案 - CORS方案此为原作者的链接:跨域问题,解决之道

  • 前端如何解决常见跨域问题

    跨域解决方案 1、 通过jsonp跨域 2、 document.domain + iframe跨域 3、 loca...

  • 开发环境跨域和生产环境跨域

    开发环境跨域 前后端分离,IP地址不同,请求数据必然导致跨域问题;解决方案:proxy设置 生产环境跨域 解决方案...

  • 浏览器跨域及其解决方案

    title: 浏览器跨域及其解决方案author: Maydate: 20220428 什么是跨域跨域的表现解决跨...

  • 跨域解决方案

    跨域解决方案 跨域解决方案有:设置document.domain,使用带src标签,JSONP,navigatio...

  • 跨域

    参考资料 HTTP访问控制(CORS)跨域解决方案跨域详解

  • Angular访问WebApi出现options方法

    解决方案: 解决跨域:

  • 跨域解决方案(史上最易懂)

    跨域总结 1.跨域思路 跨域解决方案一般分为两种:前端解决,后端解决 1.1 前端解决方案 通过前端解决的思想就是...

  • ZUUL跨域问题

    云环境中每个服务自己有跨域解决方案,而网关需要做最外层的跨域解决方案.如果服务已有跨域配置网关也有,会出现*多次配...

网友评论

    本文标题:跨域解决方案

    本文链接:https://www.haomeiwen.com/subject/mifahftx.html