欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Ajax】跨域的产生及如何解决跨域问题

程序员文章站 2024-02-21 16:56:10
...

什么是跨域? 为什么会出现跨域

浏览器为了保护用户, 保证用户安全,使用同源策略 来针对请求做出响应。
同源:
协议相同:protocol(ftp file http https 等协议)不同得协议被服务器认为不同源
域名相同:domain网站得域名必须一致。
端口相同:port默认80端口,但是不同端口也被认为跨域
以上任何不相同都被认为是跨域。

简单的说:
1 · 使用xmlHttpRequest,即我们通常说的ajax请求
2 · 浏览器做了这个事
3 · 访问的域名不同,即访问的html页面是a域名下的,但内部js发送的ajax请求的目标地址却是b域名

以上三个条件缺一不可,尤其是第三个条件,许多做移动端的同学可能都没有听过,因为移动端可以用各种http请求狂发不同的域名,但是浏览器不允许我们这么做

JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等。这是为了保证用户得安全。

说到底,跨域的原因是 前后端分离 ,跨域的目的是 安全

如何解决跨域问题(服务器代理, CORS,JSONP)

解决跨域问题的根本就是要打破上述的三个限制中的任何一个,我们可以逐个击破:

JSONP方式
jsonp是打破第一重限制,(因为)用了XMLHttpRequest就跨域,那不用这种方式了,我们来看一段jquery的带jsonp的ajax请求:

$.ajax({
   type : "GET",
   url : "http://api.map.baidu.com/geocoder/v2/",
   data:"address=河南",
   dataType:"jsonp",
   jsonp:"callback",
   jsonpCallback:"showLocation",
   success : function(data){
	   alert("成功");
   },
   error : function(data){
   	   alert("失败");
   }
});

看似用了ajax请求,其实内部完全不是那么回事,多了jsonp和jsonpCallback选项,它内部将代码翻译并把页面上的dom操作成这样:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script type='text/javascript'>
      // 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,所以这里能拿到res。
      window.showLocation = function (res) {
        console.log(res)
        //执行ajax回调
      }
    </script>
    <script src='http://api.map.baidu.com/geocoder/v2/?address=河南&callback=showLocation' type='text/javascript'></script>
  </body>
</html>

这个时候,html页面的script src标签回去访问api.map.baidu.com的服务端,由于script,img这种标签浏览器是不受xmlhttprequest限制的,可以随意访问,这个时候对应的后端代码取得address参数,最后根据双方约定好的callback参数,返回一个被包装后的json

上面我们为什么使用src标签(请求数据地址)?

script标签src允许跨域,我们利用script标签得src来访问资源,然后使用callback来承接返回得数据,并处理。

let input = document.queryselector("input")
input.oninput = function(){
    let script = document.createElement("script")
 	let url = `https://s.search.bilibili.com/main/suggest?jsoncallback=mycallback&term=${input.value}`
    script.src = url
    document.body.appendChild(script)
    script.onload = () => document.body.removeChild(script)
}
function mycallback(data){
    console.log(data)
}

其中url是我们需要请求得src,在src中拼接了一个完整得get请求,包括请求得参数请求时发送的数据,以及回调接口。
将script添加到页面中的时候,script的代码会立即解析执行,执行完成之后删除。其中mycallback是本地的函数,这个函数接受参数用于使用参数。

CORS 后台允许跨域
在后台添加允许跨域:“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

第三方(也就是代理服务器)

文章https://m.imooc.com/article/288397中是这样说的:打破不同源的限制,我只要让它同源就可以了,比如要我的静态页面是 http://a.com/index.html 动态ajax请求访问的是http://b.com/api/***
我只需要将对应的服务部署在不同的机器上,然后使用一个公共的c.com的域名作为nginx反向代理的入口域名,在将静态服务和动态服务分别挂在后面的被代理局域网服务器内,修改配置