express遇到的问题
1. 如何引入express?
cnpm install express --save
其中--save可以保存到依赖项中。
接着 var express = require("express"); 即可。这里express只是一个模块。
注意: 有时候我们会看到有人使用 npm i express --save 的方式来安装,这样也是可行的,因为 npm i 就是 npm install 的简写形式。
2. 什么是并且如何使用express-generator?
这是一个生成express的生成器,通过它,我们可以快速构建一个express架构,而无需自己繁琐的一项一项构建。
cnpn install express-generator -g (管理员方式打开命令窗口)
注意:如果是在当前目录安装就不需要使用管理员方式,但是如果全局安装,就一定要使用管理员方式。因为这里创建了一个生成器,所以就像构造函数一样可以去创建实例,那么express在命令行中就是相当于一个可执行文件, 如果不是全局安装,就必须要在express-generator的文件目录下才能执行 ,非常繁琐,但是如果全局安装,我们在任何目录下都可以执行该命令。 如:
express myapp
就可以创建一个express架构。
这里默认使用的模板引擎是jade,如果希望使用ejs模板引擎,可以是 npm -e myapp, 其中的-e就代表使用ejs模板引擎。
如下:
注意:即通过express-generator我们再执行 express <项目名称> 可以快速构建一个架构。 其中myapp就是这样一个文件,包含了package.json(此文件中的依赖项中包含了各种express所需的包),app.js(即入口文件)、pulic即其下面的一些文件夹用于存放相应的文件 ,以及路由等等。 如果不使用 express-generator ,我们就得自己一个一个的创建,这是相当麻烦的 。 另外,如果有不符合我们项目的地方,我们直接修改即可。 创建的同时提示首先 cd myapp (即进入myapp文件夹)然后 npm install(安装package.json中的依赖项),完成依赖项的安装(即package.json文件中的依赖项安装)。我们可以看到package.json中的依赖项如下:
{
"name": "myapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.17.1",
"cookie-parser": "~1.4.3",
"debug": "~2.6.3",
"express": "~4.15.2",
"jade": "~1.11.0",
"morgan": "~1.8.1",
"serve-favicon": "~2.4.2"
}
}
其中body-parser在post请求时必须使用;cookie-parser在处理cookie时必须使用; debug模块用于调试,类似于console.log; express就更不用说了;jade是模板引擎模块,这对于服务器端语言还是非常重要的。morgan是一个日志模块,用于在后台打印出req请求等等,方便我们在后台查看,这与debug模块非常相似,但是debug模块是用于取代console.log的,而morgan主要是用于查看请求的。serve-favicon不太懂,后面学习。
cd myapp
npm install
注意: 在安装过程中,会提示jade已经更名为pug,也就是说两者是一回事。
在安装完了所有的依赖项之后,我们就可以使用下面的命令来启动这个应用了:
set DEBUG=myapp:* & npm start
这里 set DEBUG=myapp:* & npm start 就可以来启动了,而前者是说启动debug模块,打印一些debug日志方便我们管理后台。 注意:和*之间有空格和没有空格是不同的。 这里使用的没有空格。
另外,如果不希望使用debug模块,像下面这样就可以启动了。
npm start
在浏览器中进入localhost:3000, 如下所示:
通过 Express 应用生成器创建的应用一般都有如下目录结构:
(补充):其中routes文件是怎么是使用的呢?
其实不用routes文件当然也是可以的,但是在实际开发中, 路由文件动辄成百上千,如果全部放在 app.js 中, 不难想象app.js将会多么臃肿, 所以我们需要对于不同路径的路由放在不同的文件下。
对于 express-generator 生成的模板, app.js 的内容如下:
var express = require('express');
var app = express();
var indexRouter = require('./routes/index');
var userRouter = require('./routes/users'); app.use('/', indexRouter);
app.use('/users', userRouter); app.listen();
然后进入routes下的index我们可以看到:
var express = require('express');
var router = express.Router(); router.get('/', function(req, res) {
res.send('hello, express');
}); module.exports = router;
其中router为express.Router() 的一个实例,这是非常重要的。
对于routes下的users也是一样的:
var express = require('express');
var router = express.Router(); router.get('/:name', function(req, res) {
res.send('hello, ' + req.params.name);
}); module.exports = router;
这样就可以很好的管理路由了,当然,不难看出,实际项目中,我们并不是真的只要这两个路由,而是根据你的项目,可能除了 index、 users, 还有其他的文件,只要保证一个路径对应一个路由文件即可,这样便可很好地管理路由了。
重要的是需要在 app.js 中使用 app.use() 挂载到不同的路径上。
易错点: 在使用 app.use() 时,第一个参数是一个相对的路径,然后使用第二个参数,即routes下的文件时, router.get("/"),这又是一个路径,最终表现在url上是两者的综合路径(叠加路径),比如app.use('/reg', index); 其中在index下的路由文件中设置的是 router.get('/reg', function (req, res) {}) , 那么最终表现出来的就是localhost:8888/reg/reg 这样的路由,这样才能正确访问, 否则就会出错。
(补)debug模块的使用。(参考教程)
在上面的例子中,我们使用 set DEBUG=myapp:* & npm start, 其中用到了debug模块, 实际上debug模块是怎么使用的呢?
nodejs的调试有很多,这里主要介绍debug模块调试,首先npm init 、npm install debug --save, 新建app.js文件,其内容如下:
var debug = require("debug")("mydebug:http"),
work = require("./work"),
http = require("http");
http.createServer(function (req, res) {
debug(req.method + " " + req.url);
res.end("hello \n");
}).listen(, function () {
debug("listening");
});
然后建立work.js,内容如下:
var debug = require("debug")("mydebug:work");
setInterval(function () {
debug("doing some work @ %s - %s", new Date().toString(), "with supervisor");
}, );
(注意:如果要debug, 就必须要在当前目录下存在 npm-debug.log 日志文件)
可以看到,这两个模块中我都使用了 debug 模块。 运行 set DEBUG=mydebug:* & node app.js ,如下:
即这里的debug语句就相当于console.log(),然后对于不同的debug,会显示不同的显色, 而mydebug是我设置的debug名称,也可以是其他的。
开启时使用的是 set DEBUG=mydebug:* & node app , 也就是说我们运行了所有的(*)debug模块,如果我们只想运行work模块,而不运行http模块,可以像下面这样:
set DEBUG=mydebug:work & node app
我们可以将&理解为并且的意思。(为什么不是&&呢?)
(补)npm start的使用原理
这里实际上是 npm run start 的简写。 参考 http://javascript.ruanyifeng.com/nodejs/packagejson.html
这里的npm start启动的是bin目录下的www,也就是说使用 express-generator 的默认的入口是 bin 下的 www, 而不是app.js ,目前很多项目都是如此, 我们可以在 package.json中进行设置,如 express-generator 中的设置如下:
{
"name": "myapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.17.1",
"cookie-parser": "~1.4.3",
"debug": "~2.6.3",
"express": "~4.15.2",
"jade": "~1.11.0",
"morgan": "~1.8.1",
"serve-favicon": "~2.4.2"
}
}
其中的 scripts 中设置了start(入口文件)为 node ./bin/www ,即当启动项目时,实际上输入的是 node ./bin/www ,只是这样设置的好处在于更加方便管理。容易理解。
比如我们创建一个文件,npm init , 创建 app.js,内容如下:
var http = require("http");
http.createServer(function (req, res) {
res.writeHead(, {"Content-Type": "text/plain; charset=utf8"});
res.write("hello");
res.end();
}).listen(, function () {
console.log("Server is running at port 127.0.0.1:8888");
});
然后node app即可启动这个项目,但是app就在这当然比较好启动,可如果入口文件藏的很深呢? 比如./bin/www就深了一层,每次 node ./bin/www可能会比较麻烦,所以在 package.json 中的scripts下添加了 start 选项,对于这个项目我们也可以添加,如下:
{
"name": "starttest",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js"
},
"author": "",
"license": "ISC"
}
即添加start项,每次npm start 就相当于 node app.js,这样的效果是一样的。
我们可以使用 npm run start 和 npm run test 都是可以执行的。 参考阮一峰教程。
(补:)package.json中的dependencies是什么? 作用如何? 和devDependencies的区别是什么?
即项目依赖项,用于告诉我们这个项目依赖了哪些模块,但这不是主要作用, 主要作用是当我们将项目上传到服务器时,可以不用上传 node_modules ,而只用上传基础文件即可, 服务器端可以直接在根目录下 npm install ,然后就可以安装package.json中所有的依赖模块了。
dev,顾名思义,是开发的意思, 而dependencies是指生产中所需要的依赖项, devDependencies 可能包括一些生产中不需要而仅在开发中需要的调试模块。
3. 路由见了很多,到底什么是路由? 句柄又是什么? 路由中有哪些常用的响应方法?
简单的理解,路由就是 路径 + 一个http方法 + 一些句柄。 下面就是一个路由文件:
// 对网站首页的访问返回 "Hello World!" 字样
app.get('/', function (req, res) {
res.send('Hello World!');
}); // 网站首页接受 POST 请求
app.post('/', function (req, res) {
res.send('Got a POST request');
}); // /user 节点接受 PUT 请求
app.put('/user', function (req, res) {
res.send('Got a PUT request at /user');
}); // /user 节点接受 DELETE 请求
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user');
其中app是一个express实例, 同时包含了路径(/ 、user)和http方法(get、post、delete、put)。
有时候我们还会见到app.all() ,这是指不论是什么方法,只要路径对了,就会执行后面的句柄。
那么什么是句柄呢? 其实句柄就是指其中的语句, 执行的函数。。。
而路由中一定是有响应方法的,比如之前一直使用的 res.send() 这样可以把其中的内容返回给页面,另外,还有下面的一些方法:
其中 res.end() 也比较常用,表示发送结束了。 res.download() 方法接受一个参数是文件的相对路由, 一旦满足路由,就会下载文件。 res.json() 即接受一个json字符串。如下:
var express = require("express");
var fs = require("fs");
var app = express();
app.get("/", function (req, res) {
res.json('{"name": "John Zhu"}');
res.end();
});
app.get("/login", function (req, res) {
res.download("./test.txt");
});
app.listen(, function () {
console.log("Server is running at localhost:3000");
});
另外,对于相同的路径,根据不同的请求方法给出不同的句柄,我们应该怎么实现呢? 可以是下面这样:
app.get("/", function (req, res) {
res.send("get");
});
app.post("/", function (req, res) {
res.send("post");
});
app.delete("/", function (req, res) {
res.send("delete");
});
app.put("/", function (req, res) {
res.send("put");
});
但是这样显然代码是冗余的,并且容易造成拼写错误,如果使用 app.route() 使用链式定义会更好,如下:
app.route("/")
.get(function (req, res) {
res.send("get");
})
.post(function (req, res) {
res.send("post");
})
.delete(function (req, res) {
res.send("delete");
})
.put(function (req, res) {
res.send("put");
});
这样更容易查看并且不容易出错。
4. express中静态文件是什么?
错! 静态文件是node中的概念,而不仅仅是express中的。 它的作用就是托管静态文件。 什么是静态文件呢? 比如我们看到一个网站上(如网易)的一个图片,然后复制图片地址,如http://img3.cache.netease.com/photo/0001/2017-04-21/CII56AJH19BR0001.jpg ,打开这个连接,发现这就是一个图片, 而这,就是静态文件。 如我们再引入图片、css、js等时,这些文件都是静态文件,由此可知,静态文件的重要性。
在使用express-generator生成应用的时候,我们就可以在那个架构中看到 public 文件,这个文件就是静态文件,其中包含了images、javascripts、stylesheets。 使用如下:
app.use(express.static("public"));
重要声明: 其中app是一个express实例,而use就代表使用一个中间件。即使用express.static()中间件。其中一定是express而不是app,这是需要格外注意的地方。
5. 刚刚也提到了中间件这个概念,那么到底什么是中间件? 怎么理解中间件中的next()方法?
在知乎上有这么一个回答,就照搬过来吧~
毫无疑问,这里的中间件的定义是便于我们理解的,我们看看官网上是怎么说的吧~
Express 是一个自身功能极简,完全是由路由和中间件构成一个的 web 开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。
中间件(Middleware) 是一个函数,它可以访问请求对象(request object (
req
)), 响应对象(response object (res
)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为next
的变量。
在express中可以使用下面的几种中间件:
应用级中间件:即我们使用的app.use() 和 app.get()之类的中间件。 通过这个我们不难理解,express的确完全是使用中间件搭建起来的。 因为app.METHOD()在服务器端语言node中使用的很多。
路由级中间件:即app.Router()的中间件
错误处理中间件:即函数的参数必须要四个,分别是 error、req、res和next。 error就是用来处理错误的。
内置中间件:express中唯一内置的中间件就是 express.static()了。
第三方中间件:如cookie-parser 这样的中间件就是第三方中间件。 还有body-parser也是的。
6. 如何在Express中使用模板引擎?
说明:模板引擎有很多,比如 jade (下面主要说的)、 ejs (也是非常常用的)等等很多。
两个步骤就可以让express来渲染模板文件:
第一: 添加放置模板的目录views, 然后app.set('views', './views');
第二: 添加模板引擎即views engine, 然后app.set('view engine', 'jade');
当然前提条件是有相应的模板引擎安装包:
npm install jade --save
之前我们使用 express-generator 的时候就可以发现目录下已经有了 views 目录, 同时 package.json 中也是有依赖项jade 的, 利用之我们可以看到在app.js中它是这样设置的。
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
当然这是一样的, set函数接受两个参数,第一个是要设置的东西,这里是模板文件(views), 第二个参数是一个路径, 不难理解,path.join() 就是为了将两个path组合到一起 。 当然,前提是引入path模块。
对于第二句使用jade模板引擎都是一样的。
然后我们再 views 下面生成以及模板文件, 如generator生成的文件就是 index.jade、layout.jade、 error.jade 这三个模板引擎。其中layout.jade如下所示:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
这个模板引擎的特有语法, 更加简洁。 在body下有一个block content, 这时就要根据不同的状态使用 index.jade 和 error.jade了, 如index.jade内容如下:
extends layout block content
h1= title
p Welcome to #{title} #{title}
很容易看出来它是对 layout.jade 的扩展, 其定义了block content的内容, 其中的title就是可以替换的变量,后面会讲到。而error.jade的内容如下:
extends layout block content
h1= message
h2= error.status
pre #{error.stack}
同样,这也是对于layout.jade 的扩展。
在哪里控制这个渲染的呢? 显然这些都与路由有关,所以在routes下的index.js中可以看到:
var express = require('express');
var router = express.Router(); /* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
}); module.exports = router;
即使用了res.render()渲染index这个模板引擎(在扩展layout的基础上),并给这个模板引擎传递参数title: 'Express', 这是以对象的形式传递的所以说我们还可以传递更多的参数。
更一般的理解: 一旦get方法访问了主页,就会将index.jade模板引擎渲染为html页面返回给用户。
开头就说了,模板引擎有很多,ejs 就是其中一种, 因为它在使用起来非常简单, 并且与 express 集成良好, 所以我们选用 ejs . (ejs官方文档)
在 express-generator 中自动生成的是jade, 所以如果不实用jade而是使用 ejs 的话,我们就要单独安装了,如下所示:
npm install ejs --save
然后,我们需要在 app.js 中添加下面的代码:
app.set('views', path.join(__dirname, 'views'));
app.set('views engine', 'ejs');
app.set('view engine', 'ejs');
也就是说使用views作为放置模板的目录。 使用ejs作为模板引擎。
注意: 设置路径时是 views ,因为模板不止一个,但是在设置模板引擎时,一定是 view engine ,而不能加s, 否则就会报错。
另外,在app.js中不需要 require("ejs") ,如果require()了也不会报错。
接下来开始设置模板, 在 views 下面添加 user.ejs,其中内容如下:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {padding: 50px;font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;}
</style>
</head>
<body>
<h1><%= name.toUpperCase() %></h1>
<p>hello, <%= name %></p>
</body>
</html>
这就是ejs的格式, 使用 <% 变量 %>将变量包裹起来。可以看到,在模板中我使用了 name.toUpperCase() 这样的js语句。
修改 routes下的 user.js 内容如下:
var express = require('express');
var router = express.Router(); router.get('/:name', function(req, res) {
res.render('users', {
name: req.params.name
});
}); module.exports = router;
这样就可以成功渲染一个html页面了。即通过 res.render() 来渲染 ejs 模板, res.render() 的第一个参数是模板的名字,这里的user会匹配 views/user.ejs , 第二个参数是传给模板的数据,这里传入了name,那么在模板中就可以使用 name 这个变量了, 所以res.render() 的作用就是将模板和数据结合成HTML,同时在响应头中设置 {"Content-Type: text/html"} 告诉浏览器我渲染的是一个html页面,而不是文本。
补充说明: ejs有下面几种常用的标签:
- <% code %> 运行js代码,不输出
- <%= code %> 显示转义后的html内容
- <%- code %> 显示原始html内容
下面的例子解释了 <% code %>的用法:
DATA:
supplies: ['mop', 'broom', 'duster']
EJS TEMPLATE:
<ul>
<% for(var i=; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>
RESULT:
<ul>
<li>mop</li>
<li>broom</li>
<li>duster</li>
</ul>
ejs --- include
我们使用模板通常并不是一个页面对应一个模板,这样模板的优势就失去了。而是把模板拆成可以复用的模板片段组合使用 (这正是我想要的)。
比如我在views下新建了 header.ejs 和 footer.ejs, 并修改了 user.ejs,如下所示:
views/header.ejs
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {padding: 50px;font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;}
</style>
</head>
<body>
views/footer.ejs
</body>
</html>
views/user.ejs
<%- include('header') %>
<h1><%= name.toUpperCase() %></h1>
<p>hello, <%= name %></p>
<%- include('footer') %>
即我们通过 incluede 方式引入了footer和header,这样,如果文件多了,利用率会更高一些。 注意: 其中 <%- ... %> 表示使用原始数据,即原来是啥就是啥。
说明: 拆分模板组件的两个好处
- 模板可以复用,减少重复代码
- 主模板更加清晰。
7.怎么理解错误处理? 如何进行错误处理?
错误处理? 即请求发生错误,或者是响应错误时,给出一定的处理方案: 如给用户提示错误信息等等。。。
错误处理也是一种中间件,之前我们就说过,express框架就是使用一大推中间件堆积起来的,错误处理中间件是一个函数, 必须有四个参数,分别是 err req res next, 值得注意的是,我们必须要在其他中间件定义完了之后,然后在定义错误处理中间件。 如下:
var bodyParser = require('body-parser');
var methodOverride = require('method-override'); app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
// 业务逻辑
});
我们可以自己测验一下,如下所示:
var express = require("express");
var app = express();
app.get('/', function (req, res) {
// 这个函数没有定义会发生错误。
god();
});
app.get('/login', function (req, res) {
res.send("登录成功!");
});
app.use(function (err, req, res, next) {
res.send("错误发生:" + err);
});
app.listen(, function () {
console.log("server is running at localhost:3000...");
});
在这里, 我们在‘/’定义了一个 get 请求,然后执行一个没有定义的函数,那么这一定会出错,然后不过不使用 app.use(function (err, req, res, next) {...}) 那么错误界面就会很乱甚至导致后台崩溃,但是如果我们使用了异常处理中间件, 就会发现, 可以通过它捕获到请求。 值得注意的是: 异常处理中间件一定要放在最后(listen之前), 这样就可以成功的异常处理了。
如下:
错误发生:ReferenceError: god is not defined
当然我们也可以打印出 错误栈(error stack), 即
res.send("错误发生:" + err.stack);
效果如下:
8. nodejs作为后台语言,怎么集成数据库?
的确,后台语言大半时间也是为了和后台打交道的,所以数据库的连接和使用格外重要。 要为nodejs连接数据库,只需要添加相应的驱动即可。下面是一些常用的数据库node模块。
这里主要讲MySQL 和 MongoDB,如下所示:
MySQL --- 首先安装mysql模块:
npm install mysql
然后连接数据库:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'dbuser',
password : 's3kreee7'
}); connection.connect(); connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[].solution);
}); connection.end();
MongoDB --- 首先安装mongoskin模块:
npm install mongoskin
然后连接数据库:
var db = require('mongoskin').db('localhost:27017/animals'); db.collection('mamals').find().toArray(function(err, result) {
if (err) throw err;
console.log(result);
});
8. app.get("/logim/:name", function () {}); 是什么意思? 那里的:的作用是什么?
其中:name是占位符的意思,如:
app.get("/login/:name", function (req, res) {
res.send(req.params.name);
});
如果我们输入 localhost:8888/login/hhh ,那么浏览器上就会显示hhh,因为我们可以通过 req.params.name 读取到这个占位符。
推荐github项目: https://github.com/nswbmw/N-blog/blob/master/book/3.3%20%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E.md
结束
express遇到的问题的更多相关文章
- 如何安全的将VMware vCenter Server使用的SQL Server Express数据库平滑升级到完整版
背景: 由于建设初期使用的vSphere vCenter for Windows版,其中安装自动化过程中会使用SQL Server Express的免费版数据库进行基础环境构建.而此时随着业务量的增加 ...
- 【原】无脑操作:express + MySQL 实现CRUD
基于node.js的web开发框架express简单方便,很多项目中都在使用.这里结合MySQL数据库,实现最简单的CRUD操作. 开发环境: IDE:WebStorm DB:MySQL ------ ...
- Express 教程 01 - 入门教程之经典的Hello World
目录: 前言 一.Express?纳尼?! 二.开始前的准备工作 三.测试安装之经典的Hello World 四.使用express(1)来生成一个应用程序 五.说明 前言: 本篇文章是建立在Node ...
- VisualStudio 2015 开启IIS Express可以调试X64项目
现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中调试.不要总是放在IIS中,在Attach这样好慢. 如果不设置直接调试X64的程序,我们有可能会受到以下类似的错误 ...
- Node.js Express连接mysql完整的登陆注册系统(windows)
windows学习环境: node 版本: v0.10.35 express版本:4.10.0 mysql版本:5.6.21-log 第一部分:安装node .Express(win8系统 需要&qu ...
- Node.js实现RESTful api,express or koa?
文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...
- express全局安装后无法通过require使用
今天入门了一下express,首先安装依赖. npm install express -g; npm install body-parser -g; npm install cookie-parser ...
- 初步认识Node 之Express
通过本文,你会对Express有一个较为具体的了解. 起源 2009年6月26日,TJ Holowaychuk提交了Express的第一次commit,接下来在2010年1月2日,有660次co ...
- 安装nodejs express框架时express命令行无效
我也是看了这篇才明白.http://jingyan.baidu.com/article/922554468a3466851648f419.html 最近在看一本书,nodejs开发指南.至于出现这个问 ...
- 从express源码中探析其路由机制
引言 在web开发中,一个简化的处理流程就是:客户端发起请求,然后服务端进行处理,最后返回相关数据.不管对于哪种语言哪种框架,除去细节的处理,简化后的模型都是一样的.客户端要发起请求,首先需要一个标识 ...
随机推荐
- WOX快速搜索
WOX wox和mac上的Aflred类似,虽然在功能上稍有逊色,但是还是可以给我们使用windows电脑带来很多福利.首先你不需要在桌面放一堆应用软件的快捷方式,桌面可以非常干净整洁,想要打开某个应 ...
- OM—>AR相关会计科目
业务会计核算 挑库: 借:发出商品 (递延销货成本) 贷:发出商品 (递延销货成本) 发运: 借:发出商品 (递延销货成本) 贷:库存商品/原材料 (库存估 ...
- 简单好用的表单校验插件——jQuery Validate基本使用方法总结
jquery validate当前最新版本是1.17.0,下载链接是:https://github.com/jquery-validation/jquery-validation/releases/t ...
- 使用VS Code编写Markdown文件
VS Code默认支持Markdown文件文件格式,这里介绍两个比较实用的功能,后续有新发现,可以持续更新. 实时预览 顾名思义,实时编辑,实时预览解析效果. 在VS Code扩展中搜索"M ...
- 同一个程序里有多个版本的App
在Xcode中添加多个targets进行版本控制,就是同一个app开发多个版本 以Xcode 9.3 为例 1. 创建 点击左侧工程项目文件,选择TARGETS 下的项目右击选择 Duplicate. ...
- 拆半搜索binary_search
//binary_search用于在有序的区间用拆半查找搜索等于某值得元素 #include<algorithm> #include<iostream> using names ...
- pycharm自动调整html页面代码缩进不正确的解决办法
pycharm自动调整html页面代码缩进不正确的解决办法
- loj#6041. 「雅礼集训 2017 Day7」事情的相似度(后缀自动机+启发式合并)
题面 传送门 题解 为什么成天有人想搞些大新闻 这里写的是\(yyb\)巨巨说的启发式合并的做法(虽然\(LCT\)的做法不知道比它快到哪里去了--) 建出\(SAM\),那么两个前缀的最长公共后缀就 ...
- sass的基本语法与使用
一.简介 SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护.以上都是百度的,哈哈: 其实个人认为sass就是一套提高编写css效率的规则 ...
- linux防火墙(二)—— iptables语法之选项和控制类型
一.语法: iptables [-t 表名] 选项 [链名] [匹配条件] [-j 控制类型] 未指定表名时,默认用filter表:链名,控制类型要大写:除非设置默认策略,否则必须指定匹配条件:不指定 ...