AJAX(三)跨域

一、同源策略

同源策略最早由Netscape公司提出,是浏览器的一种安全策略。

同源:协议、域名、端口号必须完全相同。(同一个来源)

违背同源策略就是跨域。

AJAX发送请求时是默认要遵循同源策略的,不是同源策略,没法直接发AJAX。

get.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>首页</title>
    </head>
    <body>
    <h1>沃尔</h1>
    <button>点击获取用户数据</button>
    <script>
        const btn =document.querySelector('button');
        btn.onclick=function(){
            const x=new XMLHttpRequest();
            //这里因为是满足同源策略的,所以url可以简写
            x.open('GET','/data');
            //发送
            x.send();
            x.onreadystatechange=function(){
                if(x.readyState == 4){
                    if(x.status>=200 && x.status<300){
                        console.log(x.response);
                    }
                }
            }

        }
    </script>
    </body>
</html>

app.js: 

const express=require('express');

const app=express();

app.get('/home',(request,response)=>{
   //响应一个页面
     response.sendFile(__dirname+'/index.html');
});

app.get('/data',(request,response)=>{
     response.send('用户数据');
});


app.listen(9000,()=>{
    console.log("服务已经启动...");
});

我们在网站中输入:http://127.0.0.1:9000/home:

之后再点击点击获取用户数据的按钮:

 数据都是从9000端口来的,所以为同源。同源策略就是来源于同一个服务。

如果点击按钮之后,显示状态码为304,此时删除缓存,重新刷新即可。 

二、跨域的解决方案

1.jsonp的实现原理

(1)JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。

(2)在网页上有一些标签天生具有跨域能力,比如:img link iframe script

         JSONP就是利用script标签的跨域能力来发送请求的。

get.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <title>axios 发送 AJAX请求</title>
        <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
    </head>
    <body>
       <button>GET</button>
       <button>POST</button>
       <button>AJAX</button>
       <script>
       const btns=document.querySelectorAll('button');

       //配置baseURL
       axios.defaults.baseURL='http://127.0.0.1:8000';
       btns[0].onclick=function(){
            //GET请求
            axios.get('/axios-server',{
                //url参数
                params:{
                    id:100,
                    vip:7
                },
                //请求头信息
                headers:{
                    name:'woer',
                    age:33
                }

            }).then(value =>{
                console.log(value);
            }
       )}


       btns[1].onclick=function(){
            //GET请求
            axios.post('/axios-server',{
                  username:'admin',
                  password:'admin'
               },{
                //url
                params:{
                    id:200,
                    vip:9
                },
                //请求头信息
                headers:{
                    name:'yuehanwoer',
                    age:30
                }
               });
            }

            btns[2].onclick=function(){
            axios({
                //请求方法
                method:'POST',
                //url
                url:'/axios-server',
                params:{
                    vip:10,
                    level:30
                },
                //头信息
                headers:{
                    a:100,
                    b:200
                },
                //请求体参数
                 data:{
                    username:'admin',
                    password:'admin'
                 }

            }).then(response=>{
                console.log(response);
                // //响应状态码
                // console.log(response.status);
                // //响应状态字符串
                // console.log(response.statusText);
                // //响应头信息
                // console.log(response.headers);
                // //响应体
                // console.log(response.data);
            })
            }    
        
       </script>
    </body>
</html>

此界面在浏览器中打开我们发现如下所示:

此url为file协议的,而远端的axios.js的协议为https.域名和路径都不一样,但是仍然可以使用。

使用的正是script标签。 

演示如下:

get.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>原理演示</title>
    </head>
    <body>
        
   <script src="app.js"></script>
    </body>
</html>

app.js:

const data ={
    name:'woer'
};

console.log(data);

我们进行访问: 

我们加入script标签如下所示:

原理演示.html: 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>原理演示</title>
    </head>
    <body>
        
   <script src="http://127.0.0.1:5500/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/JSONP/app.js"></script>
    </body>
</html>

我们进行访问: 

此时仍然可以响应,说明是可以跨域的。 

此时我们修改如下:

原理演示.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>原理演示</title>
        <style>
            #result{
                width: 300px;
                height:100px;
                border: solid 1px  #78a;
            }
        </style>
    </head>
    <body>
        <div id="result"></div>
    <script>
     //处理数据
        function handle(data){
           //获取result元素
           const result=document.getElementById('result');
           result.innerHTML=data.name;
     }
   </script>
   <script src="http://127.0.0.1:5500/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/JSONP/app.js"></script>
    </body>
</html>

app.js: 

const data ={
    name:'yuehanwoer'
};
handle(data);

 查看响应信息:

 此时为app.js资源给返回的结果,对里面内容做一个解析和做一个处理。

app.js:

//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO AJAX')
});
//延时响应
app.all('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//jQuery 服务
app.all('/jQuery-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    const data={name:'woer'} 
    //设置响应体
      response.send(JSON.stringify(data));
    });
//axios 服务
app.all('/axios-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
    response.send(JSON.stringify(data));
  });
  //fetch 服务
app.all('/fetch-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
  response.send(JSON.stringify(data));
  });
  //jsonp服务
app.all('/jsonp-server',(request,response)=>{
    response.send('console.log("hello jsonp-server")');
  })


//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });

  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

原理演示.html: 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>原理演示</title>
        <style>
            #result{
                width: 300px;
                height:100px;
                border: solid 1px  #78a;
            }
        </style>
    </head>
    <body>
        <div id="result"></div>
    <script>
     //处理数据
        function handle(data){
           //获取result元素
           const result=document.getElementById('result');
           result.innerHTML=data.name;
     }
   </script>
   <!-- <script src="http://127.0.0.1:5500/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/JSONP/app.js"></script> -->
   <script src="http://127.0.0.1:8000/jsonp-server"></script>
    </body>
</html>

 查看界面:

当前端向后台发送请求之后,调的是一个函数调用的内容作为结果返回。应该是一段js代码,这样子前端的引擎才能解析并执行里面的内容。

后台响应这个(直接返回一个字符串)是无法被解析的:

 response.send('hello jsonp-server');

可以解析的是如下代码:

response.send('console.log("hello jsonp-server")');

我们再进行查看如下所示:

原理.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>原理演示</title>
        <style>
            #result{
                width: 300px;
                height:100px;
                border: solid 1px  #78a;
            }
        </style>
    </head>
    <body>
        <div id="result"></div>
    <script>
     //处理数据
        function handle(data){
           //获取result元素
           const result=document.getElementById('result');
           result.innerHTML=data.name;
     }
   </script>
   <!-- <script src="http://127.0.0.1:5500/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/JSONP/app.js"></script> -->
   <script src="http://127.0.0.1:8000/jsonp-server"></script>
    </body>
</html>

service.js:

//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO AJAX')
});
//延时响应
app.all('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//jQuery 服务
app.all('/jQuery-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    const data={name:'woer'} 
    //设置响应体
      response.send(JSON.stringify(data));
    });
//axios 服务
app.all('/axios-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
    response.send(JSON.stringify(data));
  });
  //fetch 服务
app.all('/fetch-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
  response.send(JSON.stringify(data));
  });
  //jsonp服务
app.all('/jsonp-server',(request,response)=>{
    const data={
      name:'woer'
    };
    //将数据转换为字符串
    let str= JSON.stringify(data);
    //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
    response.end(`handle(${str})`);
  });


//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });

  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

此时响应之后如下所示: 

返回的结果的形式是一个函数调用,而这个函数的参数是我们想给客户端返回的结果数据,这个函数前端必须要提前声明,要不然的话回来之后没有这个函数就会报错。 

2.原生jsonp实践

案例.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>案例</title>
    </head>
    <body>
      用户名:<input type="text" id="username">
      <p></p>
      <script>
        //获取input元素
        const input =document.querySelector('input');
        const p =document.querySelector('p');
        //声明 handle函数
        function handle(data){
          input.style.border="solid 1px #f00";
          //修改 p标签的提示文本
          p.innerHTML=data.msg;
        }

        //绑定事件,丧失焦点事件是onblur
        input.onblur=function(){
            //获取用户的输入值
            let username= this.value;
            //向服务端发送请求 检测用户名是否存在
            //1.创建script标签
            const script=document.createElement('script');
            //2.设置标签的src属性
            script.src='http://127.0.0.1:8000/check-username';
            //3.将script插入到文档中,将script标签插入到body标签的最后
            document.body.appendChild(script);
        }
      </script>
    </body>
</html>

 onblur:

 onblur 事件发生在对象失去焦点时。

onblur 事件 (w3school.com.cn)

appendChild():

appendChild() 方法可向节点的子节点列表的末尾添加新的子节点。

HTML DOM appendChild() 方法 | 菜鸟教程 (runoob.com)

document.createElement:

在 HTML 文档中,Document.createElement() 方法用于创建一个由标签名称 tagName 指定的 HTML 元素。如果用户代理无法识别 tagName,则会生成一个未知 HTML 元素 HTMLUnknownElement。

语法:

var element = document.createElement(tagName[, options]);
//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO AJAX')
});
//延时响应
app.all('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//jQuery 服务
app.all('/jQuery-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    const data={name:'woer'} 
    //设置响应体
      response.send(JSON.stringify(data));
    });
//axios 服务
app.all('/axios-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
    response.send(JSON.stringify(data));
  });
  //fetch 服务
app.all('/fetch-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
  response.send(JSON.stringify(data));
  });
  //jsonp服务
app.all('/jsonp-server',(request,response)=>{
    const data={
      name:'woer'
    };
    //将数据转换为字符串
    let str= JSON.stringify(data);
    //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
    response.end(`handle(${str})`);
  });

 //用户名检测是否存在
 app.all('/check-username',(request,response)=>{
  const data={
   exist:1,
   msg:'用户名已经存在'
  };
  //将数据转换为字符串
  let str= JSON.stringify(data);
  //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
  response.end(`handle(${str})`);
});




//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });

  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

后台返回的数据: handle({exist:1, msg:'用户名已经存在'}),在前台的handle函数继续进行处理,然后在页面上体现出来。

3.jQuery发送JSONP请求

get.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>jQuery-jsonp</title>
        <style>
            #result{
                width: 300px;
                height:100px;
                border: solid 1px  #089;
            }
        </style>
         <script crossorigin="anonymous"src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    </head>
    <body>
       <button>点击发送 jsonp 请求</button>
       <div id="result">

       </div>
       <script>
        $('button').eq(0).click(function(){
          $.getJSON('http://127.0.0.1:8000/jQuery-jsonp-server?callback=?',function(data){
            $('#result').html(`
                名称:${data.name}<br>
                校区:${data.city}
                `)
          });
        })
      
       </script>
    </body>
</html>

$.getJSON:

通过 HTTP GET 请求载入 JSON 数据。

在 jQuery 1.2 中,您可以通过使用 JSONP 形式的回调函数来加载其他网域的 JSON 数据,如 "myurl?callback=?"。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 注意:此行以后的代码将在这个回调函数执行前执行。

 jQuery ajax - getJSON() 方法 (w3school.com.cn)

 service.js:

//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO AJAX')
});
//延时响应
app.all('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//jQuery 服务
app.all('/jQuery-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    const data={name:'woer'} 
    //设置响应体
      response.send(JSON.stringify(data));
    });
//axios 服务
app.all('/axios-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
    response.send(JSON.stringify(data));
  });
  //fetch 服务
app.all('/fetch-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
  response.send(JSON.stringify(data));
  });
  //jsonp服务
app.all('/jsonp-server',(request,response)=>{
    const data={
      name:'woer'
    };
    //将数据转换为字符串
    let str= JSON.stringify(data);
    //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
    response.end(`handle(${str})`);
  });

 //用户名检测是否存在
 app.all('/check-username',(request,response)=>{
  const data={
   exist:1,
   msg:'用户名已经存在'
  };
  //将数据转换为字符串
  let str= JSON.stringify(data);
  //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
  response.end(`handle(${str})`);
});

//
app.all('/jQuery-jsonp-server',(request,response)=>{
  const data={
   name:'woer',
   city:['北京','上海','深圳']
  };
  //将数据转换为字符串
  let str= JSON.stringify(data);
  //接收callback参数
  let cb=request.query.callback;

  //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
  response.end(`${cb}(${str})`);
});



//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });

  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

callback: 

回调就是一个在另外一个函数执行完后要执行的函数

JavaScript基础——回调(callback)是什么?-CSDN博客

回调成功之后会在网址里面体现出来,同时数据体现出来: 

4. 设置CORS响应头实现跨域

CORS,跨域资源共享,CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

CORS是通过设置一个响应头来告诉浏览器,该请求运行跨域,浏览器收到该响应以后就会对响应放行。

JavaScript基础——回调(callback)是什么?-CSDN博客

get.html: 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>CORS</title>
        <style>
            #result{
                width: 300px;
                height:100px;
                border: solid 1px  #089;
            }
        </style>
         <script crossorigin="anonymous"src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    </head>
    <body>
       <button>发送请求</button>
       <div id="result">

       </div>
       <script>
     const btn= document.querySelector('button');

     btn.onclick=function(){
           //1.创建对象
           const x=new XMLHttpRequest();
           //2.初始化设置
           x.open("GET","http://127.0.0.1:8000/cors-server");
           //3.发送
           x.send();
           //4.绑定事件,处理响应结果
           x.onreadystatechange=function(){
            if(x.readyState==4){
                if(x.status>=200 && x.status<300){
                    //输出响应体
                    console.log(x.response);
                }
            }
           }
    }
       </script>
    </body>
</html>

service.js: 

//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO AJAX')
});
//延时响应
app.all('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//jQuery 服务
app.all('/jQuery-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    const data={name:'woer'} 
    //设置响应体
      response.send(JSON.stringify(data));
    });
//axios 服务
app.all('/axios-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
    response.send(JSON.stringify(data));
  });
  //fetch 服务
app.all('/fetch-server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  const data={name:'woer'} 
  //设置响应体
  response.send(JSON.stringify(data));
  });
  //jsonp服务
app.all('/jsonp-server',(request,response)=>{
    const data={
      name:'woer'
    };
    //将数据转换为字符串
    let str= JSON.stringify(data);
    //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
    response.end(`handle(${str})`);
  });

 //用户名检测是否存在
 app.all('/check-username',(request,response)=>{
  const data={
   exist:1,
   msg:'用户名已经存在'
  };
  //将数据转换为字符串
  let str= JSON.stringify(data);
  //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
  response.end(`handle(${str})`);
});

//
app.all('/jQuery-jsonp-server',(request,response)=>{
  const data={
   name:'woer',
   city:['北京','上海','深圳']
  };
  //将数据转换为字符串
  let str= JSON.stringify(data);
  //接收callback参数
  let cb=request.query.callback;

  //返回结果,end不会加特殊响应头,其中的符号`为按英文键的~.
  response.end(`${cb}(${str})`);
});

//
app.all('/cors-server',(request,response)=>{
 //设置响应头
  response.setHeader('Access-Control-Allow-Origin','*');
  response.setHeader('Access-Control-Allow-Headers','*');
  response.setHeader('Access-Control-Allow-Method','*');
  response.send('Hello CORS');
});


//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });

  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

此时成功响应出来: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/295961.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | Neck篇 | 利用ASF-YOLO改进特征融合层(适用于分割和目标检测)

一、本文介绍 本文给大家带来的改进机制是ASF-YOLO(发布于2023.12月份的最新机制),其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中,ASF-YOLO在2018年数据科学竞赛数据集上取得了卓越的分割准确性和速度,…

C 程序员进阶之路常备口袋的 10 个宝藏

虽然 Java 和 Python 等更现代的语言公认容易学习&#xff0c;但 C 基本上都是大学计算机类相关课程的入门语言。为什么&#xff1f;这。。。 C 语言的重要性&#xff0c;有很多理由可以说服你。最重要的还是因为学习 C 是以后学习更高级语言的良好基础&#xff0c;绝大部分现…

mysql5.7安装-windows安装版本

下载地址 官网地址:https://www.mysql.com/官网下载地址:https://dev.mysql.com/downloads/mysql/阿里云镜像站下载:https://mirrors.aliyun.com/mysql/华为云镜像站地址:https://mirrors.huaweicloud.com/home华为云镜像站下载:https://mirrors.huaweicloud.com/mysql/Downlo…

如何实现安卓端与苹果端互通的多种方案

随着移动设备用户的爆炸性增长&#xff0c;跨平台应用开发变得尤为重要。在Android与iOS之间实现互通对于推广应用、增加用户覆盖面和提升用户体验有至关重要的作用。以下是实现Android与iOS互通的多种方案&#xff0c;以及每种方案的实现方法、细节注意点、适合团队的规模和建…

大数据Doris(五十):数据导出的其他导出案例参考

文章目录 数据导出的其他导出案例参考 一、​​​​​

macosx编译qgroundcontrol源码(Qt6.7)

1.克隆源码: clone --recursive http://github.com/mavlink/qgroundcontrol.git 克隆成功 3.编译 编译环境要求: 编译方法: 使用QtCreator编译 使用命令行编译 打开QGroundControl.pro并编译IOS版本 旧版本使用Qt 5.15.2 run qmake 新版本使用Qt 6.6或者更高 IOS工程输出要…

模板模式实现分布式锁实战

前言 分布式锁相信大家都有用过&#xff0c;常见的分布式锁实现方式例如redis、zookeeper、数据库都可以实现&#xff0c;而我们代码中强引用这些分布式锁的代码&#xff0c;那么当我们以后想替换分布式锁的实现方式时&#xff0c;需要修改代码的成本会很高&#xff0c;于是我…

[足式机器人]Part2 Dr. CAN学习笔记-动态系统建模与分析 Ch02-6频率响应与滤波器

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-动态系统建模与分析 Ch02-6频率响应与滤波器 1st order system 一阶系统 低通滤波器——Loss Pass Filter

stm32学习笔记:TIM-输出比较

四部分讲解内容&#xff0c;本文是第二部分 输出比较主要用于PWM波形的控制电机&#xff08;驱动电机的必要条件&#xff09; 1、定时器基本定时&#xff0c;定一个时间&#xff0c;然后让定时器每隔一段时间产生一个中断&#xff0c;来实现每隔一个固定时间执行一段程序的目…

oracle 补齐数字长度 to_char踩坑

oracle的to_char网上找到的说明如下 &#xff08;1&#xff09;用作日期转换&#xff1a; to_char(date,格式); select to_date(2005-01-01 ,yyyy-MM-dd) from dual; select to_char(sysdate,yyyy-MM-dd HH24:mi:ss) from dual; &#xff08;2&#xff09;处理数字&#xf…

SwiftUI之深入解析如何使用accessibilityChartDescriptor视图修饰符为视图构建音频图表

一、DataPoint 结构体 在 SwiftUI 中构建一个简单的条形图视图开始&#xff0c;该视图使用垂直条形显示一组数据点。如下所示&#xff0c;有一个 DataPoint 结构&#xff0c;用于描述条形图视图中的条形&#xff0c;它具有 id、标签、数值和填充颜色&#xff1a; struct Data…

Unity添加所有场景到BuildSettings

Unity添加所有场景到BuildSettings using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.IO; public class Tools : Editor {[MenuItem("Tools/添加所有场景到BuildSettings")]static void CheckSceneSetting(){List<string&…

docker 部署haproxy cpu占用特别高

在部署mysql 主主高可用时&#xff0c;使用haproxy进行负载&#xff0c;在服务部使用的情况下发现服务器cpu占比高&#xff0c;负载也高&#xff0c;因此急需解决这个问题。 1.解决前现状 1.1 部署配置文件 cat > haproxy.cfg << EOF globalmaxconn 4000nbthrea…

简易机器学习笔记(十)Windows下 PaddlePaddle配置CUDA加速环境

前言 大伙既然都来做这个了&#xff0c;那配个CUDA环境肯定是必不可少的了吧&#xff08;笑&#xff09; 最前面的最前面&#xff0c; 流程 确定当前设备支持的CUDA版本安装CUDA Toolkit 和 GPU版的Paddlepaddle下载cuDNN Archive手动放置配套的cuDNN到指定文件夹测试 1.确…

HDU - 2063 过山车(Java JS Python C)

题目来源 Problem - 2063 (hdu.edu.cn) 题目描述 RPG girls今天和大家一起去游乐场玩&#xff0c;终于可以坐上梦寐以求的过山车了。 可是&#xff0c;过山车的每一排只有两个座位&#xff0c;而且还有条不成文的规矩&#xff0c;就是每个女生必须找个男生做partner和她同坐…

使用STM32微控制器驱动LCD1602显示器

驱动LCD1602显示器是嵌入式系统常见的任务之一&#xff0c;而STM32微控制器因其灵活性和丰富的外设而成为了广泛采用的解决方案。在这篇文章中&#xff0c;我们将探讨如何使用STM32微控制器来驱动LCD1602显示器。我们将从STM32的GPIO配置、延时函数以及LCD1602的初始化和写入数…

【数值分析】非线性方程求根,牛顿法,牛顿下山法,matlab实现

4. 牛顿法 收敛时牛顿法的收敛速度是二阶的&#xff0c;不低于二阶。如果函数有重根&#xff0c;牛顿法一般不是二阶收敛的。 x k 1 x k − f ( x k ) f ′ ( x k ) x_{k1}x_k- \frac{f(x_k)}{f(x_k)} xk1​xk​−f′(xk​)f(xk​)​ matlab实现 %% 牛顿迭代例子 f (x) x…

【信息论与编码】习题-填空题

目录 填空题1.克劳夫特不等式是判断&#xff08; &#xff09;的充要条件。2.无失真信源编码的中心任务是编码后的信息率压缩接近到&#xff08;&#xff09;限失真压缩中心任务是在给定的失真度条件下&#xff0c;信息率压缩接近到&#xff08; &#xff09;。3.常用的检纠错方…

使用 KubeSphere 与极狐GitLab 打造云原生持续交付系统

极狐GitLab 简介 极狐GitLab 是一个一体化的 DevOps 平台&#xff0c;可以简单理解为 GitLab 在国内的“发行版”。是由极狐(GitLab)公司推出的产品&#xff08;极狐(GitLab)公司是以“中外合资3.0”模式成立的公司&#xff0c;在国内独立运营&#xff0c;为国内用户提供适合本…

CSS 实现两个圆圈重叠部分颜色不同

这是期望实现的效果&#xff0c;由图可知&#xff0c;圆圈底图透明度是0.4&#xff0c;左侧要求重叠部分透明度是0.7&#xff0c;所以不能通过简单的透明度叠加来实现最右侧的效果。 这就需要另外新建一个图层来叠加在两个圆圈重叠上方。 直接看代码 .circle_hight {width: 1…