最近工作中遇到了跨域问题,其实这个名词我一直都能听别人提起,但是确实没有仔细研究过,因此我会通过几篇系列文章,记录下我学习的过程。今天的这篇文章主要从以下2个方面来介绍:

  • 为什么会有跨域?
  • 单机上重现跨域问题

为什么会有跨域

跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。这里需要注意是form的请求是不会有跨域问题的,只有ajax的请求才会有跨域问题。

那浏览器为什么要限制ajax跨域,而form的不限制呢?

跨域本身解决的是防止CSRF攻击,比如说有两个网站 A和B。你是A的用户,你在A网站可以删除用户,加入你登录到另一个危险的网站B, 网站B 有一个按钮,这个按钮被按下时会发送一个删除请求到A网站,而你还浑然不知。因此浏览器处于这个考虑,不允许跨域名的调用。那其实还有没有解释另一个问题:为什么form的不限制呢?因为原页面用 form 提交到另一个域名之后,原页面的脚本无法获取新页面中的内容。所以浏览器认为这是安全的。而 AJAX 是可以读取响应内容的,因此浏览器不能允许你这样做。如果你细心的话你会发现,其实请求已经发送出去了,服务器确实给出了响应,但是浏览器把它拦截了。

单机上重现跨域问题

主机环境是mac,所以我先用brew install nginx下载一个nginx, 你也可以使用其他的web服务器,我这里就从最简单的入手。

  • 更新本地hosts文件 vim /etc/hosts,加入2个解析:

127.0.0.1 backend.com
127.0.0.1 frontend.com

  • 在本地某一个目录/tmp/crossdomain新建一个index.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            $("a").click(function(){
                $.ajax({
                    type:'post',
                    url:'http://backend.com:9001/setname',
                    data:$("#myform").serialize(),
                    cache:false,
                    dataType:'json',
                    success:function(data){
                        alert("请求成功");
                    }
                });
            });
        });
    </script>
</head>
<body>
<form action="" id="myform">
    用户名<input type="text" name="name"/>
</form>

<a href="#" style="text-decoration: none;">使用ajax提交表单数据</a>
</body>
</html>
  • 新建一个spring boot项目,在其中一个controller中加入/setname的请求处理,启动的端口号是9001:
@RequestMapping("/setname")
public String test(@RequestParam(name = "name") String name) {
    return name;
}
  • 修改nginx配置, vim /usr/local/etc/nginx/nginx.conf, 将其中的一个server修改为:

listen 80;
server_name frontend.com;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root /tmp/crossdomain;
index index.html index.htm;
}

  • 启动nginx和spring boot, 访问http://frontend.com, 输入一个随便的内容,点击提交链接, 打开chrome的控制台你会发现红色的错误出现:No ‘Access-Control-Allow-Origin’ header is present on the requested resource, 这个就是典型的跨域问题

总结

这篇文字介绍了跨域问题的来源以及如何在本地重现跨域问题,方便我们实地操演,了解内部原理,后面的文章会继续介绍如何解决跨域问题。

 

欢迎关注我的个人的博客www.zhijianliu.cn, 虚心求教,有错误还请指正轻拍,谢谢

版权声明:本文出自志健的原创文章,未经博主允许不得转载

发表评论

电子邮件地址不会被公开。