【前端】跨域 问题 原理 + 解决方案 下

版权声明:高性能MySQL是第3版,注意mysql版本;很多博客都参考或者直接转载自网络,如果不方便被转载,看到请与我联系 https://blog.csdn.net/ma15732625261/article/details/82260890

前言:

     上一篇的排版好难看,字体都不能设置,我们可不可以不悲伤——怎么可能

正文:

先复习一下jsonp,上图一张【


 

iFrame解决跨域

如果两个网页不同源,就无法拿到对方的DOM:iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信

document.getElementById("myIFrame").contentWindow.document
// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
window.parent.document.body
// 报错

1、如果两个窗口一级域名相同,二级域名不同,设置document.domain拿到DOM(共享cookie)

A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要script中设置相同的document.domain,两个网页就可以共享Cookie、拿到DOM

document.domain = 'example.com';

 A通过脚本设置cookie:document.cookie = "test1=hello";B可以读到var allCookie = document.cookie;

 

对应完全不同源的网站,三种方法,解决:

1、片段识别符fragment identifier

fragment identifier指URL的#后部分,只是改变片段标识符,页面不会刷新

父窗体将信息写入子窗口的片段标识符:

var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

子窗口监听hashchange得到通知:

window.onhashchange = checkMessage;

function checkMessage() {
  var message = window.location.hash;
  // ...
}

同样,子窗口可改变父窗口的片段标识符:

parent.location.href= target + "#" + hash;

这个博客有更详细的介绍 boystar iFrame跨域解决办法 https://www.cnblogs.com/boystar/p/6909214.html 

 

window.name:全局window对象的属性

无论是否同源,只要在同一个窗口里,前一个网页设置这个属性,后一个网页可以读取它:

当iframe中加载新页面时,name属性值不变

仅同域名的iframe可访问; 数据量大:2M   安全  多种数据格式 

父窗口先打开子窗口,载入不同源的网页,该网页将信息写入window.name

window.name=data

接着,子窗口跳回一个与主窗口同域的网址:

location=‘http://parent.url.com/xxx.html’

主窗口可以读取子窗口的window.name

var data = document.getElementById('myFrame').contentWindow.name;

window.postMessage:HTML5

跨文档通信API cross document messaging,为window对象新增window.postMessage方法,容许窗口通信、不论是否同源

父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage

var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送;

 

子窗口向父窗口发送消息的写法类似

window.opener.postMessage('Nice to see you', 'http://aaa.com');

通过message事件,监听对方的消息

window.addEventListener('message', function(e) {
  console.log(e.data);
},false);


window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
  //属性引用父窗口,发送消息
  event.source.postMessage('Nice to see you!', '*');
}

//event.origin属性过滤不是发给本窗口的消息
window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
  if (event.origin !== 'http://aaa.com') return;
  if (event.data === 'Hello World') {
      event.source.postMessage('Hello', event.origin);
  } else {
    console.log(event.data);
  }
}

 

localStorage:借助上、读取其他窗口的localstorage

window.onmessage = function(e) {
  if (e.origin !== 'http://bbb.com') {
    return;
  }
  var payload = JSON.parse(e.data);
  //子窗口将父窗口发来的消息,写入自己的LocalStorage
  localStorage.setItem(payload.key, JSON.stringify(payload.data));
};

 

webSocket:通信协议

使用ws://和wss://(加密)作为协议前缀,只要服务器支持,跨源通信

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com//请求源(origin),哪个域名

nginx配置:

server{
    # 监听9099端口
    listen 9099;
    # 域名是localhost
    server_name localhost;
    #凡是localhost:9099/api这个样子的,都转发到真正的服务端地址http://localhost:9871 
    location ^~ /api {
        proxy_pass http://localhost:9871;
    }    
}

 

服务端处理跨域流程 

服务器处理跨域请求流程图

兜兜转转到这里,后端@CrossOrigin、filter、还有一个全局的配置宝宝都试了,无效

jsonp需要服务器端支持,起码返回值前要加个callback吧,然鹅笨宝动不了服务端,见都没有见过,只是调一下貌似没有必要见,虽然我挺想见的,估计不难,iframe吧也不行,我不是要父子交互而是类似窗体跳转的效果,点击授权弹出成功登录界面,想想还有什么,jsonp!~已经pass了,nginx、调方法的是遇到了跨域,勉强跨域接收,这个耗了偶太长时间,要放弃时,猜、我看到了什么!

为什么form表单提交没有跨域问题,但ajax提交有跨域问题?

我的天、竟然这样,试试吧、你猜、竟然可以了!!!果然转发的好运微博没白转啊,哈哈~三个叹号都不足以表达我的心情,为什么一开始就完美地错过了呐?还是见识少的原因啊

ajax跨域是因为浏览器需要保护用户的安全和隐私而给js设定的限制

原页面form提交到另一个域名后,它的脚本无法获取新页面内容,不会把结果返回给js,浏览器认为是安全的:给别人发请求不拿数据;

而ajax可以读取响应的内容,浏览器不容许这样做:请求发出去了,但是响应数据被浏览器截取;


王宁博  跨域的那些事儿  这篇也不错 

写Bug 不要再问我跨域的问题了 https://segmentfault.com/a/1190000015597029

 阮一峰 浏览器同源政策及其规避方法 :http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

LLeo小浩 一篇文章可以解决跨域 https://www.imooc.com/article/19869?block_id=tuijian_wz 最后这个霸气的图的发源地,上篇简单请求的导图也盗于此

猜你喜欢

转载自blog.csdn.net/ma15732625261/article/details/82260890