0.前言
先前都是使用表单进行 get post请求
- 主要是不跨域
- 先熟悉下整个前后端的交互流程
1.客户端html
这里面引用
jQ
的话就尽量先使用CDN
的形式直接使用id的形式是不规范的写法
<input type="text" placeholder="姓名" id="nameI"> <input type="text" placeholder="年龄" id="ageI"> <button> ajax_get </button> <button> ajax_post </button> <script> // get $("button").eq(0).click(function(){ $.ajax({ type: "get", url: "http://127.0.0.1:8866/getApi", data: { name: nameI.value, age: ageI.value }, dataType: "JSON", success: function (res) { // 注意返回的是数字 还是字符串 if(res.code*1 == 1000){ alert(res.msg) }else{ alert(res.msg) } } }); }) // post $("button").eq(1).click(function(){ $.ajax({ type: "post", url: "http://127.0.0.1:8866/postApi", data: { name: nameI.value, age: ageI.value }, dataType: "JSON", success: function (res) { console.log(res) } }); }) </script>
2.服务端
url模块解析req.url
url.parse(req.url, true)
es6语法
let { pathname } = urlObj let {name,age} = urlObj.query
req.method
注意大写
简单的正则
主要逻辑JS代码
对象压缩成字符串
res.write(JSON.stringify(data));
var server = http.createServer((req, res) => { res.writeHead(200, { "content-type": "text/html;charset=utf-8" }) let urlObj = url.parse(req.url, true) // 路径 接口 let { pathname } = urlObj console.log("pathname", pathname); if (req.method == "GET") { if (pathname == "/favicon.ico") { let readS = fs.createReadStream(__dirname + "/favicon.ico") readS.pipe(res) } else if (/(.*)\.html$/.test(pathname)) { // 怎么判断 是网页的 // 判断后缀是 .html结尾 // \.html$ 以.html结尾 // . 在正则里面除 \n换行符以为的任意字符 // * 出现任意次数 >=0 let readS = fs.createReadStream(__dirname + pathname) readS.pipe(res) }else if(pathname == "/"){ res.end("默认主页请求") }else if(pathname == "/getApi"){ let {name,age} = urlObj.query // 数字 字符串 let data = {} if(name === "王阳明" && age === "20"){ //自己写接口 data = { code:1000, msg:"登录成功" } }else{ data = { code:2000, msg:"用户名错误" } } // write(字符串) // 对象转字符串 res.write(JSON.stringify(data)); res.end() } else { // 养成好的习惯 写else res.end("get-结束") } } else if (req.method == "POST") { let allData = "" // 监听数据传递 req.on("data",function(chunk){ allData+=chunk }) // 数据传输结束 req.on("end",function(){ // 需要转为 对象 // 引用 querystring 模块 console.log("数据:",allData); let qsObj = qs.parse(allData) let {name ,age} = qsObj let data = {} if(name === "吴X清" && age=== "20"){ data = { code:1000, msg:"登录成功" } }else{ data = { code:1000, msg:"登录失败" } } res.write(JSON.stringify(data)) res.end() }) } else { res.end("其他请求") } })
3.调试
之前的都是用本地网页打开或者vscode插件 LiveServer打开 ,表单提交,
这个是 纯粹的ajax 会跨域,所以 get post 请求
需要地址栏输入 下面的形式 替换成你的端口和文件名字就行
http://127.0.0.1:8866/2-ajax.html
4. jsonp
- jsonp 是解决跨域的的一种办法,所以jsonp请求可以用常规方式 客户端网页测试
2.跨域是前端请求可以发出去
3.服务器也能接收到 前端发出的请求,给响应
4.但是浏览器把响应给拦截了 ,所以收不到
- 解决办法就是前后端沟通一个回调函数
- 后端回调这个 回调函数
5.客户端jsonp代码
注意
dataType: "jsonp",
$("button").eq(0).click(function () { $.ajax({ type: "get", url: "http://127.0.0.1:8866/jsonpApi", data: { name: nameI.value, age: ageI.value, }, // 默认是 json dataType: "jsonp", //默认值就是callback jsonp: "callback", //回调函数的 属性/key jsonpCallback: "getData" //回调函数的 值 /value }); }) function getData(data) { console.log("jsonp回调:", data) if(data.code*1 == 1000){ // 处理图片的 看第7条 $("img").eq(0).prop("src",data.images[0]) $("img").eq(1).prop("src",data.images[1]) } alert(data.msg) } //调用 // getData(123)
6. 服务端jsonp代码
先梳理通jsnop的原理
再往下看完整的处理逻辑
es6的一些语法
if (pathname === "/jsonpApi") { console.log("jsonp进来了"); / / res.end("getData(1")) //以上就是简易的 jsonp工作前后端的 方式 console.log("输出参数:", urlObj.query); // getData 是前端 和后端约定的 回调函数 let { callback, name, age } = urlObj.query // 后端一般都是严格匹配 let data = { code: 2000, msg: "登录失败" } if (name === "张小龙" && age === "30") { data = { code: 1000, msg: "登录成功", images: ["http://127.0.0.1:8866/img/1.jpg", "http://127.0.0.1:8866/img/2.jpg" ] } } // end(字符串) // 把指定内容压缩成字符串 var dataStr = JSON.stringify(data) res.end(`${callback}(${dataStr})`) // res.end("getData(1")) // 可以用传统的拼接 + }
7. 客户端图片显示
根据上方的代码 服务端返回客户端图片资源路径
客户端把地址赋值给img但图片还是不显示
把地址赋值给
img
的src
属性的时候其实又发起了请求,结合之前的综合练习思考下所以还需要服务端把 图片资源返回给客户端
服务端核心代码
if(/(.*)\.(png|jpg|jpeg|gif|bmp)$/.test(pathname)){ console.log("-----img"); let readS = fs.createReadStream(__dirname + pathname) readS.pipe(res) }