前端ajax如何实现跨域

43 阅读4分钟

跨域产生的原因:浏览器同源策略

浏览器在发送数据请求时,必须满足同源策略才能访问这一资源,同源策略(协议,域名,端口三者必须完全相同),网站资源如果不是在部署的服务器上就会被浏览器拦截,而大多数的情况下,网站资源跟部署的不会在同一个服务器上,这样可以让网站性能提升,对用户友好,要是想访问不是当前部署服务器上的资源,这就需要跨域操作。

解决跨域的几种方式

1. 后端解决

在后端响应头中携带 " Access-Control-Allow-Origin " : " * "

  这种方式对于前端开发人员来说是最爽不过的了,在公司你只需要厚着脸皮去和后端开发人员说:兄弟,你在响应头中写那么一句话:" Access-Control-Allow-Origin ":" * ",嘿嘿,你的跨域就解决啦,当然我们在开发的过程当中可能会用到别人的后台数据,那么你也可以和别人公司的后台开发人员说加那么一句话,对方就会和你说一个非常感人的故事:滚!

  有时候让后端去操作是很复杂的事,虽然只是一句代码。当然是你这个全栈大佬自己把后端的活也干了那就可以这么做。

2. 前后端一起解决

jsonp 方式解决跨域

  jsonp解决跨域完全是搁那卡浏览器的bug,浏览器会对其他发送请求数据的方式进行限制,但是对于不管是我们的script标签的src还是img标签的src,或者说link标签的href他们没有被同源策略所限制。其会向目标地址发送get请求(只支持get请求,不接受追问了,想知道自己去查吧)。所以聪明的程序员就卡bug绕过了浏览器的同源策略去拿到数据,当然了,这种方式也得需要我们的后端配合。

解决方式:

后端会将数据以函数实参的形式放在一个函数中并返回,前端需要定义好这个函数,(其实也可以和后端商量让你自己定义这个函数名的,也不难,就把函数名当成变量而已嘛)不然数据回来之后找不到方法执行,前端只需要在定义好的参数中接收和处理数据即可。

  • 前端事先定义好一个同名的回调函数:
    <script>
      /* JSONP的回调函数 */
      function fn(obj) {
        /* 处理拿到的数据 */
        console.log("data=", obj);
        const cities = obj.data.cities;
        cities.forEach((item) => console.log(item.name));

        /* 删除无用的script标签 */
        document.querySelectorAll(".jsonp").forEach(sc=>sc.remove())
      }
    </script>
  • 前端在需要进行跨域数据请求时,创建一个script标签,并将目标地址写入src中:
    <script>
      btn.onclick = function(e){
        /* 动态地创建script标签 */
        const sc = document.createElement("script")

        // 声明通信地址
        sc.src = "http://localhost:8000/files/jsonp/cities"

        // 添加一个class以便拿到数据后删除之(卸磨杀驴)
        sc.classList.add("jsonp")

        // 将script标签丢到页面上并立即执行
        document.body.appendChild(sc)
      }
    </script>
  • 后端只需要在收到请求之后返回一个函数,将数据塞到入参即可,还不理解的话就当成后端调用前端的方法,方法调用的时候是不是要传参,你就把数据当成参数传进去就好了。ok,解决!

3. 前端解决

通过代理(正向反向都行)的方式,毕竟求人不如求己。求人家后端,不可能,绝对不可能,那我以后写bug的时候还怎么理直气壮的甩锅给后端!代理的方式是解决跨域最常用的手段,因为它比较霸气(开玩笑的),我们知道浏览器向别人的服务器发送请求会受到同源策略限制,那不简单了嘛,我向自己的服务器发就不会有同源策略的影响啦,但是!!!我们的服务器可没有我们想要的数据,那咋办,嘿,让我们的服务器向别人的服务器发请求拿数据,再转发给我们就好了,同源策略管得了浏览器可管不了我服务器。

代理的方式其实有很多种,我更喜欢 nginx 代理的方式,简单方便。

图片1.png

  • 新建一个文件夹(这里我叫dist ,名字任意,也可以用默认的,但一般不用)要记住这个文件名!!!!待会配置的时候会用到!!!!

图片2.png

  • 打开conf文件夹

图片3.png

  • 找到ndinx.conf 文件,用vscode打开

图片4.png  

  • 修改默认的根目录 (未修改前是 html ===> dist)dist是前面创建的文件夹名!!!!!!

图片5.png

  • 配置代理 可以配置多个

图片6.png

服务的启动和关闭

启动服务:.\nginx.exe -c conf\nginx.con

关闭服务:.\nginx.exe -s stop

并不支持点击 exe 文件打开,所以必须要输入指令,开启之后想重启就必须先关掉,至少我用的时候是这样。