项目搭建
先创建一个文件夹
初始化包
cnpm init -y
安装express和ejs
cnpm install express
cnpm install ejs
创建static,views等文件夹,创建app.js,和html文件,并且在app.js文件中写入以下代码:
右键----run code----启动端口
在网页中输入:
http://localhost:90/static/html/index.html
测试能否访问到静态资源(页面出现index页面即是成功)
http://localhost:90/a
测试能否访问到动态资源(页面出现内容‘aaaa’即成功)
在启动窗口出现下面的错误
- 是因为端口号被占用,于是我把原来的80窗口改成了90。就可以了
-
E:\VSCode>node "e:\VSCode\Nodejs\22-Day8\02-pratiseProject\app. events.js:174 throw er; // Unhandled 'error' event ^ Error: listen EACCES: permission denied 0.0.0.0:80 at Server.setupListenHandle [as _listen2] (net.js:1262:19) at listenInCluster (net.js:1327:12) at Server.listen (net.js:1414:7) at Function.listen (E:\VSCode\Nodejs\22-Day8\02-pratiseProj@4.17.1@express\lib\application.js:618:24) at Object.<anonymous> (e:\VSCode\Nodejs\22-Day8\02-pratiseP at Module._compile (internal/modules/cjs/loader.js:776:30) at Object.Module._extensions..js (internal/modules/cjs/load at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:58 Emitted 'error' event at: at emitErrorNT (net.js:1306:8) at process._tickCallback (internal/process/next_tick.js:63: at Function.Module.runMain (internal/modules/cjs/loader.js: at startup (internal/bootstrap/node.js:283:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
上面页面运行成功,就说明已经搭建好。
接下来就是开始项目…
----------------------------------------------------(返回的数据是html格式的)
在index.html里写入:
<div class="box">
<div id="product">
<h1 id="title">商品标题名称</h1>
<img src="" alt="">
<p id="des">商品描述信息</p>
</div>
<div id="buttons">
<button name="clothes">女装</button>
<button name="bag">包包</button>
<button name="slipper">拖鞋</button>
</div>
</div>
写入样式:
* {
margin: 0;
padding: 0;
}
.box {
width: 300px;
height: 400px;
border: 1px solid #000;
margin: 50px auto;
text-align: center;
background: rgb(252, 226, 230);
}
h1 {
margin: 10px;
}
img {
width: 200px;
height: 250px;
display: block;
margin: 10px auto;
border: 1px solid #000;
}
p {
margin: 10px;
text-align: center;
background: coral;
}
button {
background-color: palevioletred;
padding: 5px 10px;
margin: 0 10px;
border: 0;
border-radius: 5px;
outline: none;
}
button:hover {
box-shadow: 0 0 10px peru;
}
写入js:(这里是原生的js写的)
var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// console.log(this);
// console.log(this.name);
var ajax = new XMLHttpRequest();
ajax.open('get', '/product?name=' + this.name);
ajax.onload = function () {
if (ajax.status == 200) {
// 拿到服务器响应的数据做dom操作
// console.log(ajax.responseText);
document.getElementById("product").innerHTML = ajax.responseText;
}
}
// 发出
ajax.send();
}
}
在app.js文件中,写入后端代码,
运行出现错误:
ReferenceError: image is not defined
at app.get (e:\VSCode\Nodejs\22-Day8\02-pratiseProject\app.js:35:30)
at Layer.handle [as handle_request] (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\layer.js:95:5)
at next (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\route.js:137:13)
at Route.dispatch (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\layer.js:95:5)
at E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\index.js:281:22
at Function.process_params (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\index.js:335:12)
at next (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\index.js:275:10)
at expressInit (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\middleware\init.js:40:5)
at Layer.handle [as handle_request] (E:\VSCode\Nodejs\22-Day8\02-pratiseProject\node_modules\_express@4.17.1@express\lib\router\layer.js:95:5)
错误原因:<img src="${ product[image] }" alt="">
模板字符串这里面的那段代码,可以这么写:
<p id="title">${ product['title']}</p>
<p id="title">${ product.title}</p>
正确后端代码:
const express = require('express');
const path = require('path');
const { title } = require('process');
var app = express();
app.use('/static', express.static(path.join(__dirname, 'static')));
// 假数据
let products = {
clothes: {
title: "甜美女装",
des: "人见人爱,花见花开......",
image: "/static/images/clothes.jpg"
},
bag: {
title: "清新包包",
des: "包治百病........",
image: "../images/bag.jpg"
},
slipper: {
title: "可爱拖鞋",
des: "可爱拖鞋,你值得拥有......",
image: "/static/images/slipper.jpg"
}
}
app.get('/product', (req, res) => {
let name = req.query.name;
let product = products[name];
let data =
`
<h1 id="title">${ product.title}</h1>
<img src="${ product.image}" alt="">
<p id="des">${ product.des}</p>
`
res.type('html');
res.send(data);
});
app.listen(90, () => console.log('启动了90端口'));
此时,只需要启动服务器,就可以访问了。
-
每次手动"右键----run code":即
node “e:\VSCode\Nodejs\22-Day8\02-pratiseProject\app.js”
-
或者,第一次手动输入,后面保存就会自动重启:
nodemon “e:\VSCode\Nodejs\22-Day8\02-pratiseProject\app.js”
难受,打错个单词,(-_-!)。。。啊啊啊,文件名‘practise…’少打了个c!!!
模板引擎方式:
const express = require('express');
const path = require('path');
const { title } = require('process');
var app = express();
// 使用模板引擎的方式,要再加这两句全局...
app.set('views',path.join(__dirname,'views'));//模板引擎的路径
app.set('view engine','ejs')//使用的模板引擎技术
app.use('/static', express.static(path.join(__dirname, 'static')));
// 假数据
let products = {
clothes: {
title: "甜美女装",
des: "人见人爱,花见花开......",
image: "/static/images/clothes.jpg"
},
bag: {
title: "清新包包",
des: "包治百病........",
image: "../images/bag.jpg"
},
slipper: {
title: "可爱拖鞋",
des: "可爱拖鞋,你值得拥有......",
image: "/static/images/slipper.jpg"
}
}
app.get('/product', (req, res) => {
let name = req.query.name;
let product = products[name];
res.type('html');
/*
let data =
`
<h1 id="title">${ product.title}</h1>
<img src="${ product.image}" alt="">
<p id="des">${ product.des}</p>
`
res.send(data);
*/
// 上面两段,相当于下面这句:
res.render('productList',product);
});
app.listen(90, () => console.log('启动了90端口'));
模板引擎文件
在views文件夹中创建:productList.ejs文件,并写入:
<h1 id="title"><%= title %></h1>
<img src="<%= image %>" alt="">
<p id="des"><%= des %></p>
此时,只需要启动服务器,就可以访问了。
出现过下面的错误:
<h1 id="title">${ product.title}</h1>
^
SyntaxError: Unexpected token <
at Module._compile (internal/modules/cjs/loader.js:721:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
[nodemon] app crashed - waiting for file changes before starting...
找不到哪里错了,后来重启VSCode软件就好了
使用JQuery方式发送请求:
下载jquery到js文件夹里,导入jquery包:
<script src="../js/jquery.js"></script>
jquery方式的发送ajax请求的代码:
$('#buttons > button').click(function(){
// console.log(this);
$.get('/product?name='+$(this).attr('name'),function(data){
// console.log(data);
$('#product').html(data);
});
});
使用axios发送ajax请求:
导入axios:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
axios代码:(这里用jquery操作dom了,以后应该配合vue使用)
$('#buttons > button').click(function(){
var name=$(this).attr('name');
axios.get('/product?name='+name)
.then(function(response){
// console.log(response);
$('#product').html(response.data);
});
});
----------------------------------------------------(返回的数据是html格式的)
----------------------------------------------------(返回的数据是xml格式的)
模板字符串方式:
app.js中写入:
const express = require('express');
const path = require('path');
const { title } = require('process');
var app = express();
app.use('/static', express.static(path.join(__dirname, 'static')));
// 假数据
let products = {
clothes: {
title: "甜美女装",
des: "人见人爱,花见花开......",
image: "/static/images/clothes.jpg"
},
bag: {
title: "清新包包",
des: "包治百病........",
image: "../images/bag.jpg"
},
slipper: {
title: "可爱拖鞋",
des: "可爱拖鞋,你值得拥有......",
image: "/static/images/slipper.jpg"
}
}
app.get('/productXML', (req, res) => {
let name = req.query.name;
let product = products[name];
res.type('xml');
let data =
`
<product>
<title>${ product.title}</title>
<des>${ product.des}</des>
<image>${ product.image}</image>
</product>
`
res.send(data);
});
app.listen(99, () => console.log('启动了99端口'));
原生js:
<script>
//原生js方式:
var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
var ajax = new XMLHttpRequest();
ajax.open('get', '/productXML?name=' + this.name);
ajax.onload = function () {
if (ajax.status == 200) {
// console.log(ajax.responseXML);
// 返回的是一个文档对象
var xmlData =ajax.responseXML;
var title= xmlData.getElementsByTagName('title')[0].innerHTML;
var image= xmlData.getElementsByTagName('image')[0].innerHTML;
var des= xmlData.getElementsByTagName('des')[0].innerHTML;
// console.log(title);
document.getElementById('title').innerHTML=title;
document.getElementById('des').innerHTML=des;
document.getElementsByTagName('img')[0].src=image;
}
}
// 发出
ajax.send();
}
}
复制绿框中的路径,用谷歌浏览器直接打开是下这样子的就是成功了
模板引擎方式:
和前面一样,在app.js文件中添加:
app.set('views',path.join(__dirname,'views'));//模板引擎的路径
app.set('view engine','ejs')//使用的模板引擎技术
修改模板字符串的那段代码为:
res.render('productXml',product)
看一下,运行的界面:
使用JQuery方式发送请求:
//jquery方式:
$('#buttons > button').click(function(){
$.get('/productXML?name='+$(this).attr('name'),function(data){
var $data=$(data);
var title = $data.find('title').html();
var des = $data.find('des').html();
var image = $data.find('image').html();
$('#title').html(title);
$('#des').html(des);
$('img').attr('src',image);
});
});
写这段代码时,出现了下面的错误,找了半天竟然是因为把 var title = $data.find('title').html();
错写成了 var title = $data.find('title').html;
jquery.js:6358 Uncaught TypeError: this.empty is not a function
at HTMLHeadingElement.<anonymous> (jquery.js:6358)
at access (jquery.js:4167)
at HTMLHeadingElement.html (jquery.js:6325)
at access (jquery.js:4184)
at jQuery.fn.init.html (jquery.js:6325)
at Object.success (indexXML.html:108)
at fire (jquery.js:3496)
at Object.fireWith [as resolveWith] (jquery.js:3626)
at done (jquery.js:9786)
at XMLHttpRequest.<anonymous> (jquery.js:10047)
使用axios发送ajax请求:
// axios方式:
$('#buttons > button').click(function () {
var name = $(this).attr('name');
axios.get('/productXML?name=' + name)
.then(function (response) {
// console.log(response);
var xmlData = response.data;
// $.parseXML(xmlData) 转成dom对象
var $data = $($.parseXML(xmlData));
var title = $data.find('title').html();
var des = $data.find('des').html();
var image = $data.find('image').html();
$('#title').html(title);
$('#des').html(des);
$('img').attr('src', image);
});
});
----------------------------------------------------(返回的数据是xml格式的)
----------------------------------------------------(返回的数据是json格式的)
在app.js文件中写入:
const express = require('express');
const path = require('path');
const { title } = require('process');
var app = express();
app.use('/static', express.static(path.join(__dirname, 'static')));
// 假数据
let products = {
clothes: {
title: "甜美女装",
des: "人见人爱,花见花开......",
image: "/static/images/clothes.jpg"
},
bag: {
title: "清新包包",
des: "包治百病........",
image: "../images/bag.jpg"
},
slipper: {
title: "可爱拖鞋",
des: "可爱拖鞋,你值得拥有......",
image: "/static/images/slipper.jpg"
}
}
app.get('/productJSON', (req, res) => {
let name = req.query.name;
let product = products[name];
res.json(product);//相当于做了: res.type('json'); res.send(JSON.stringify(product));
});
app.listen(99, () => console.log('启动了99端口'));
原生js:
//原生js方式:
var btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
var ajax = new XMLHttpRequest();
ajax.open('get', '/productJSON?name=' + this.name);
ajax.onload = function () {
if (ajax.status == 200) {
// console.log(ajax.responseText);
// 转成js对象
var product = JSON.parse(ajax.responseText);
document.getElementById('title').innerHTML=product.title;
document.getElementById('des').innerHTML=product.des;
document.querySelector('img').src=product.image;
}
}
// 发出
ajax.send();
}
}
使用JQuery方式发送请求:
jquery会根据响应头Content-Type的值来判断,若响应数据类型是application/json它在调用函数之前会把响应的数据转成js对象
//jquery方式:
$('#buttons > button').click(function(){
$.get('/productJSON?name='+$(this).attr('name'),function(data){
// jquery会根据响应头Content-Type的值来判断,若响应数据类型是application/json它在调用函数之前会把响应的数据转成js对象
$('#title').html(data.title);
$('#des').html(data.des);
$('img').attr('src',data.image);
});
});
使用axios发送ajax请求:
底层也会帮我们直接转成js对象
// axios方式:
$('#buttons > button').click(function () {
var name = $(this).attr('name');
axios.get('/productJSON?name=' + name)
.then(function (response) {
// console.log(response);
$('#title').html(response.data.title);
$('#des').html(response.data.des);
$('img').attr('src', response.data.image);
});
});