教你搞懂什么是跨域,如何解决跨域?

跨域:

一个域名下的网站向另外一个域名下的网站请求资源(静态文件)css

好比: 引用别的网站的css link 标签 引入别的网站的js 文件,可是 浏览器有同源策略.有的人会问? 同源策略是啥?html

同源策略:

所谓同源(即指在同一个域)就是两个页面具备相同的协议(protocol),主机(host)和端口号(port)前端

浏览器规定ajax请求只能使用来自于本身网站的数据,不容许使用本身网站之外的数据。
(1). 浏览器容许ajax向其它网站发送请求
(2). 浏览器也容许ajax接收其它网站的响应
(3). 可是浏览器会检查响应数据的来源(origin):
a. 若是数据来源的服务器地址和当前网页所在的地址相同,才能使用数据
b. 若是数据来源的服务器地址和当前网页所在的地址不一样,就不容许使用数据 -----同源策略 (cross orgin resoures shareing)node

跨域的几种类型:

下面这些状况都属于跨域,请牢记.jquery

(1). http://www.a.com  ->  http://www.b.com  **域名不一样**
(2). http://oa.tedu.com  ->  http://hr.tedu.com **子域名不一样**
(3). http://localhost:3000 -> http://localhost:8080  **端口号不一样**
(4). http://12306.cn    ->  https://12306.cn    **协议不一样**

 

 

特别提示: 若是你是在一台电脑上进行跨域测试的话 localhost 和127.0.0.1 这就能够实现跨域操做了.ajax

跨域怎么解决?

1.若是你的后端是node.js 开发的话 安装expres中间件cors
(1). 项目本地安装cors模块: npm i -save cors
(2)npm

app.use(cors({
              origin:['http://localhost:8080', "http://127.0.0.1:5500"],
              credentials:true
        }))

 

2.服务端CORS跨域: 让服务器端在返回数据前,修改响应头中的来源json

地址与前端服务器地址同样。
服务端接口返回数据时,不要用res.send(result) 由于 res.send()里面封装好了浏览器的源头.
应该:后端

  res.writeHead(200,{
          "Access-Control-Allow-Origin":"http://127.0.0.1:5500" //和前端项目所在服务器的地址保持一致
        });
        res.write(JSON.stringify(result));
        res.end();

 

 

不过这个方法的缺点就是你每一个路由都要修改响应头信息.跨域

3.jsonp

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可让网页从别的域名(网站)那获取资料,即跨域读取数据。
既然ajax不能够发起跨域请求 可是标签能够 script的属性 src="" 能够实现跨域的请求 可是咱们如何 把这个数据接收到呢?
首先看下服务器端的代码 ,我用的是node.js 中http 模块 和url 模块

const http=require("http");
// 引入bodyparse 中间件
const url=require("url")
// 建立服务器
http.createServer((req,res)=>{
        var weather="北京 晴 4-24"
        res.writeHead(200,{
            "Content-Type":"text/plain; charset=utf-8"
        })
        // jqery 用callback
       
        var fname=url.parse(req.url,true).query.callback
        var stmt =`${fname}("${weather}")`
        res.write(stmt)
        res.end()
 }).listen(8080)
//  解析url  对象

 

 

浏览器代码 要用到jquery 将数据类型改成"jsonp" 你会发现已经实现了跨域请求.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="jquery-1.11.3.js"></script>
</head>
<body>
    <button>今日天气</button>
   

   
    //  <!-- <script src="http://localhost:8080?fname=show"></script> -->
</body>
 <script>
         $("button").click(function(){
        //    $(`  <script src="http://localhost:8080?fname=show">`)
        //       .appendTo("body")
           $.ajax({
              url:"http://localhost:8080",
              type:"get",
              dataType:"jsonp",
              success:function(result){
                 console.log(result)
              }    })
        })
 
        // function show(data){
        //      alert(data)
            
        //    } 
    </script>
</html>

 

不少人都很好奇,$ajax()不是不能够跨域? 若是你只看表面那就错了,
接下来和你们探讨下底层原理.

****首先ajax是绝对不能进行跨域,为啥 jquery 实现了呢, 那是jquery dataType:"jsonp"的 里面封装的是这样的一个函数这就是原理.

$(`  <script src="http://localhost:8080?fname=show">`)
             .appendTo("body")
             //在页面建立一个函数 这个函数的做用 对应的是
           
             function show(data){
             $("body>script:last").remove()
            alert(data)
            
        }

 

这句话啥意思呢就是,点击按钮建立一个script 并加到body 标签的最后,并在全局下建立一个函数 这个函数的做用呢:

         **// 服务端 返回的其实一个函数调用语句 show()**
             调用以后,并删除<script>标签.
      
      点击按钮 调用函数 ,调用完script 标签 并删除他,防止页面中多余的script 的标签.
相关文章
相关标签/搜索