分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

web 通信类

发布时间:2023-09-06 01:44责任编辑:顾先生关键词:暂无标签

1、什么是同源策略级限制?

2、前后端如何通信?

3、如何创建ajax?

4、跨域通信的几种方式?

什么是同源策略限制:

先解释什么是源,然后再解释

源:协议,域名,端口  三个有其中一个不一样,就是不同源,

就是不是同一个源不能操作另外一个源的东西

主要限制在以下三个方面:

cookie、localstorage 和indexDB无法读取

DOM无法获得

ajax请求不能发送

前后端如何通信

Ajax(同源策略限制)  WebSocket(不受同源策略限制)  CORS(支持同源也支持不同源)

如何创建ajax?

XMLHttpRequest对象的工作流程

兼容性处理

事件触发的条件

事件的触发顺序

创建对象xhr ->open() ->send() 

响应 xhr.onload = function(){}

/**
* [json 实现ajax的json]
* @param ?{[type]} options [description]
* @return {[type]} ????????[description]
*/
util.json = function (options) {
????var opt = {
????????url: ‘‘,
????????type: ‘get‘,
????????data: {},
????????success: function () {},
????????error: function () {},
????};
????util.extend(opt, options);
????if (opt.url) {
????????var xhr = XMLHttpRequest
???????????? new XMLHttpRequest()
???????????: new ActiveXObject(‘Microsoft.XMLHTTP‘);
????????var data = opt.data,
????????????url = opt.url,
????????????type = opt.type.toUpperCase(),
????????????dataArr = [];
????????for (var k in data) {
????????????dataArr.push(k + ‘=‘ + data[k]);
????????}
????????if (type === ‘GET‘) {
????????????url = url + ‘?‘ + dataArr.join(‘&‘);
????????????xhr.open(type, url.replace(/\?$/g, ‘‘), true);
????????????xhr.send();
????????}
????????if (type === ‘POST‘) {
????????????xhr.open(type, url, true);
????????????xmlhttp.setRequestHeader(‘Content-type‘, ‘application/x-www-form-urlencoded‘);
????????????xhr.send(dataArr.join(‘&‘));
????????}
????????xhr.onload = function () {
????????????if (xhr.status === 200 || xhr.status === 304) {
????????????????var res;
????????????????if (opt.success && opt.success instanceof Function) {
????????????????????res = xhr.responseText;
????????????????????if (typeof res ==== ‘string‘) {
????????????????????????res = JSON.parse(res);
????????????????????????opt.success.call(xhr, res);
????????????????????}
????????????????}
????????????} else {
????????????????if (opt.error && opt.error instanceof Function) {
????????????????????opt.error.call(xhr, res);
????????????????}
????????????}
????????};
????}
};

跨域通信的几种方式

JSONP:img中的src,link的href,script 中的src这三个都不符合同源策略,但是它们都能跨域获取资源,jsonp就是利用script的这个特点来实现跨域获取数据的

它只支持GET请求而不支持POST等其它类型的HTTP请求

jsonp是由两部份组成的,回调函数和数据

Hash: url#后面的就是hash,hash改变,页面不刷新 缺点:另外由于URL大小的限制,支持传递的数据量也不大。

postMessage:

优缺点:

 优点:方便,安全,有效的解决了跨域问题

 缺点:万恶的资本主义,ie8+才支持,而且ie8+<ie10只支持iframe的方式。

WebSocket:

CORS:

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制

CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

 浏览器发出CROS请求,就是在头信息增加一个origin字段,这个字段用来说明本次请求来自哪个源,服务器会根据这个源绝对是否同意这次请求

jsonp

 ???<div class="left" id="left">left</div>
???<div class="right">right</div>
</section>
<script type="text/javascript" charset="utf-8">
???document.getElementById(‘left‘).onclick = function () {
???????var script = document.createElement(‘script‘);
???????script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
???????document.body.insertBefore(script,document.body.firstChild)
???}
???function handleResponse(res){
???????console.log(‘res‘,res)
???}
</script>

hash

原理是利用location.hash来进行传值。

假设域名a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息。

1) cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面

2) cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据

3) 同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一旦有变化则获取获取hash值

注:由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于a.com域名下的一个代理iframe

代码如下:

先是a.com下的文件cs1.html文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function startRequest(){
 var ifr = document.createElement(‘iframe‘);
 ifr.style.display = ‘none‘;
 ifr.src = ‘http://www.cnblogs.com/lab/cscript/cs2.html#paramdo‘;
 document.body.appendChild(ifr);
}
 
function checkHash() {
 try {
  var data = location.hash ? location.hash.substring(1) : ‘‘;
  if (console.log) {
   console.log(‘Now the data is ‘+data);
  }
 } catch(e) {};
}
setInterval(checkHash, 2000);

cnblogs.com域名下的cs2.html:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//模拟一个简单的参数处理操作
switch(location.hash){
 case ‘#paramdo‘:
  callBack();
  break;
 case ‘#paramset‘:
  //do something……
  break;
}
 
function callBack(){
 try {
  parent.location.hash = ‘somedata‘;
 } catch (e) {
  // ie、chrome的安全机制无法修改parent.location.hash,
  // 所以要利用一个中间的cnblogs域下的代理iframe
  var ifrproxy = document.createElement(‘iframe‘);
  ifrproxy.style.display = ‘none‘;
  ifrproxy.src = ‘http://a.com/test/cscript/cs3.html#somedata‘; // 注意该文件在"a.com"域下
  document.body.appendChild(ifrproxy);
 }
}

a.com下的域名cs3.html

?
1
2
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

// 利用hash,场景是当前页面 A 通过iframe或frame嵌入了跨域的页面 B
?????/

postMessage

postMessage实现跨域

   语法:window.postMessage(msg,targetOrigin)

    window: 指目标窗口,可能是window.frames属性的成员或者由window.open方法创建的窗口

    message:要发送的消息,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果

    targetOrigin:“目标域“,包括:协议、主机名、端口号。若指定为”*“,则表示可以传递给任意窗口,指定为”/“,则表示和当前窗口的同源窗口。

    获取postMessage传来的消息:为页面添加onmessage事件

1 window.addEventListener(‘message‘,function(e) {2 ????3 }

    onmessage事件接受一个参数e,它是一个event对象。

    e的几个重要属性:

      1、data:postMessage传递过来的msg

      2、发送消息的窗口对象

      3、origin:发送消息窗口的源(协议+主机+端口号)

     来写一个简单的demo:

     http://source.com/source.html用来发送数据:

1 <iframe id="iframe" src="http://target.com/target.html"></iframe>2 <input id="msg" type="text" placeholder="请输入要发送的消息">3 <button id="send">发送</button>
1 window.onload =function() {2 ????document.getElementById(‘send‘).onclick = function() {3 ????var msg = document.getElementById(‘msg‘).value;4 ????var iframeWindow = document.getElementById(‘iframe‘).contentWindow;5 ????iframeWindow.postMessage(msg,"http://target.com/target.html");6 ????}7 }

     http://target.com/target.html用来接收数据:  

1 <div>2 ????<h2>target.html,以下是接收到的消息:</h2>3 ????<section id="msg">4 ????????5 ????</section>6 </div>
 1 window.onload = function() { 2 ?3 ????if(window.addEventListener){ 4 ????????window.addEventListener("message", handleMessage, false); 5 ????} 6 ????else{ 7 ????????window.attachEvent("onmessage", handleMessage); 8 ????} ??9 10 ????function handleMessage(event) {11 ????????event = event || window.event;12 13 ????????if(event.origin === ‘http://source.com‘) {14 ????????????document.getElementById(‘msg‘).innerHTML = event.data;15 ????????}16 ????}17 }

// Websocket【参考资料】http://www.ruanyifeng.com/blog/2017/05/websocket.html

var ws = new WebSocket(‘wss://echo.websocket.org‘);

ws.onopen = function (evt) {
?????????console.log(‘Connection open ...‘);
?????????ws.send(‘Hello WebSockets!‘);
?????};

?????ws.onmessage = function (evt) {
?????????console.log(‘Received Message: ‘, evt.data);
?????????ws.close();
?????};

?????ws.onclose = function (evt) {
?????????console.log(‘Connection closed.‘);
?????};

// CORS【参考资料】http://www.ruanyifeng.com/blog/2016/04/cors.html
?????// url(必选),options(可选)
?????fetch(‘/some/url/‘, {
?????????method: ‘get‘,
?????}).then(function (response) {

?????}).catch(function (err) {
???????// 出错了,等价于 then 的第二个参数,但这样更好用更直观
?????});

web 通信类

原文地址:https://www.cnblogs.com/liangshuang/p/8495449.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved