宁泽林_NiZerin - 互联网技术博客

  • PHP
  • Go
  • Java
  • Rust
  • Python
  • 交流群
  • 关于我
  • 留言版
  1. 首页
  2. JavaScript
  3. 正文

JavaScript之跨域解决方式

2018年12月4日 3075点热度 0人点赞 0条评论

平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种,希望能帮助到大家:

1.jsonp解决跨域问题

客户端代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jsonp-跨域</title>
<script type="text/javascript" src="resources/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    function callbackFn(data){
        data = typeof data != 'string' ? JSON.stringify(data) : data;
        console.log('callback:'+data);
    }
    function jsonpFn(){
        $.ajax({
            type:"get",
            dataType:"jsonp",
            url:"http://localhost:9393/ccy_server/server.jsp",
            jsonpCallback:"callbackFn",
            success:function(data){
                data = typeof data != 'string' ? JSON.stringify(data) : data;
                console.log('success.data:'+data);
            }
        });
    }
    function ajaxFn(){
        var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        var url = "http://localhost:9393/ccy_server/server.jsp";
        xmlhttp.onreadystatechange = function(){
            if(xmlhttp.readyState==4){
                if(xmlhttp.status==200){
                    callbackFn(xmlhttp.responseText);
                }
            }
        }
        xmlhttp.open('GET',url,true);
        xmlhttp.send(null);
    }
    ajaxFn();
    //jsonpFn();
</script>
</head>
<body>
</body>
</html>

服务端代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    String result = "{\"name\":\"ccy\",\"age\":18,\"info\":{\"address\":\"wuhan\",\"interest\":\"playCards\"}}";
    out.println("callbackFn("+result+")");
%>

相信大家对此种方式并不陌生,需要引用jquery库文件,并且要与服务端进行协调处理。

我先写了个简单的ajax调用非同源的异步请求直接报错

执行jsonpFn方法

成功获取服务端信息!

2.window.name解决跨域问题

在客户端浏览器中每个页面都有一个独立的窗口对象window,默认情况下window.name为空,在窗口的生命周期中,载入的所有页面共享一个window.name并且每个页面都有对此读写的权限,window.name会一直存在当前窗口,但存储的字符串不超过2M。

http://localhost:8383/ccy_client/window_name.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
    window.name = "我是 window.name 字符串";
    setTimeout(function(){
        window.location = "http://localhost:9393/ccy_server/window_name.html";
    },2000);
</script>
</head>
<body>
</body>
</html>
http://localhost:9393/ccy_server/window_name.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
    var str = window.name;
    console.log('ccy_server.window_name:'+str);
</script>
</head>
<body>
</body>
</html>

chrome打印信息

" data-src="https://user-gold-cdn.xitu.io/2018/12/2/1676f2f4ec55c056?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" data-width="758" data-height="42" />

上面是以window.location跳转的方式获取window.name字符串信息,平时开发中经常需要异步获取,请继续往下看:

http://localhost:8383/ccy_client/window_name_iframe.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
</head>
<body>
<script type="text/javascript">
    var boo = false;
    var iframe = document.createElement('iframe');
    var loadData = function() {
        if (boo) {
            var data = iframe.contentWindow.name;    //获取window.name
            console.log(data);
            //销毁数据
            iframe.contentWindow.document.write('');
            iframe.contentWindow.close();
            document.body.removeChild(iframe);
        } else {
            boo = true;
            iframe.contentWindow.location = "";    // 设置的代理文件,iframe重新载入
        }
    };
    iframe.src = 'http://localhost:9393/ccy_server/window_name_iframe.html';
    if (iframe.attachEvent) {
        iframe.attachEvent('onload', loadData);
    } else {
        iframe.onload  = loadData;
    }
    document.body.appendChild(iframe);
</script>
</body>
</html>
http://localhost:9393/ccy_server/window_name_iframe.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>window.name-跨域</title>
<script type="text/javascript">
    window.name = '我是 http://localhost:9393/ccy_server/window_name_iframe.html';
</script>
</head>
<body>
</body>
</html>

chrome打印信息

成功获取非同源地址的数据信息,主要是通过iframe的src属性,类似含有src属性的标签都可以成功处理跨域问题img,script

3.postMessage解决跨域问题

h5新特性,window.postMessage(msg,targetOrigin);

msg:传入的字符串信息

targetOrigin:目标源(协议主机端口有效)

同样借助iframe进行跨域操作

http://localhost:8383/ccy_client/postMessage.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>postMessage-跨域</title>
</head>
<body>
<iframe id="ifr" src="http://localhost:9393/ccy_server/postMessage.html" style="display: none;"></iframe>
<br>
<input id="txt" type="text" style="width:600px;height:70px;"/>
<br>
<input id="btn" type="button" value="获取9393数据" onclick="getData();" style="width:180px;height:60px;"/>
<script type="text/javascript">
    var data;
    function handleMsg(e){
        e = e || event;
        data = e.data;
        console.log('8383:'+e.data);
    }
    if(window.addEventListener){
        window.addEventListener('message', handleMsg);
    }else{
        window.attachEvent('onmessage', handleMsg);
    }
    function getData(){
        document.getElementById('txt').value=data;
        var msg = 'http://localhost:8383/ccy_client/postMessage.html';
        window.frames[0].postMessage(msg, 'http://localhost:9393');
    }
</script>
</body>
</html>
http://localhost:9393/ccy_server/postMessage.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>postMessage-跨域</title>
</head>
<body>
<script type="text/javascript">
    function handleMsg(e){
        e = e || event;
        console.log('9393:'+e.data);
    }
    if(window.addEventListener){
        window.addEventListener('message', handleMsg);
    }else{
        window.attachEvent('onmessage', handleMsg);
    }
    window.onload = function(){
        var msg = '我是 http://localhost:9393/ccy_server/postMessage.html';
        window.parent.postMessage(msg, 'http://localhost:8383');
    }
</script>
</body>
</html>

chrome打印信息

成功获取非同源数据,将非同源地址嵌入获取数据页面窗口。

4.Java解决跨域问题

通过客户端页面的ajax异步请求同源页面,再通过Java的HttpURLConnect或者HttpClient进行转换即可,此处就不再赘述。

还有一种就是设置服务端的Header,公司产品ggly的api就是这么处理的。

5.参考资料

www.sojson.com/blog/121.ht…

www.jianshu.com/p/43ff69d07…

《JavaScript权威指南》

作者:蟹丸
来源:掘金

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: js
最后更新:2018年12月4日

NiZerin

博主已经躺平了,后面很少会更新博客。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

分类
  • Angular
  • CSS3
  • docker
  • Flutter
  • git
  • Go
  • H5
  • Java
  • JavaScript
  • Laravel
  • linux
  • Node.js
  • PHP
  • Python
  • React
  • redis
  • Vue.js
  • windows
  • WordPress
  • 交流
  • 小程序
  • 工具
  • 网站公告
标签聚合
php wordpress javascript translations vue go laravel flutter
友情链接
  • PHP函数字典
  • 宝塔运维特惠
  • 科学上网
  • 阿里云特惠

COPYRIGHT © 2021 nizer.in. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang