前端-js開發
課堂完結后欲復習鞏固也方便后續-重游-故寫此篇
從實現功能過渡到涉及的相關知識點
知識點 |
1、 JS 是前端語言,是可以被瀏覽器“看到”的,當然也可以被修改啊,被瀏覽器禁用網頁的 JS 功能啊之類的。所以一般都是前后端分離開發,前端只負責顯示與提醒用戶。
2、 JS 是可以在瀏覽器里調試的,斷點之類的都行,瀏覽器里也有控制臺可以執行命令。
3、 瀏覽器不可能看到所有的 JS 文件,但是斷點也帶來了其他可能,只要斷在你想知道參數的地方,那么沒有顯示的 JS 文件也不行影響到你,畢竟你只需要它們運行而非一定得拿到源碼。
登錄驗證
簡單流程:(最初實驗版)前端 js 發送用戶名和密碼給后端,后端判斷是否正確后返回參數,js依據參數決定是否進行頁面跳轉與彈窗
分析問題:
1、 前端語言是可以看到的,是可以被改變的,所以不能給前端跳轉頁面的權力,只能做提醒,不然會導致安全問題。
前端語言應只供展示與簡單提醒
Code:
前端 js 部分代碼如下:
<!-- 采用js傳輸,php驗證-->
<body><h3>用戶登錄</h3><div><label for="username">用戶名:</label><input type="text" class="username" name="username" required></div><br><div><label for="password">密碼:</label><input type="password" class="password" name="password" required></div><br><button>登錄</button>
</body><!-- //導入jquery --><script src="./js/js/jquery-3.7.1.js"></script>
<!-- 都是鍵值對!!! -->
<script>$('button').click(function(){$.ajax({url: "check_login.php",data: {user:$('.username').val(),passwd:$('.password').val()},type: "POST",dataType: "json",success: function(data) {console.log(data);if(data.info==1){alert('登陸成功!');// location.href="index.php";/*** 安全漏洞出現,原因:前端代碼不可進行操作,只需要提示就可以了* * 小寫,哦~*/}else{console.log('登陸失敗!');}},error: function(text) {alert('登陸失敗!');}});});</script>
文件上傳
簡單流程:前端 js 判斷文件格式等是否正確,然后發送給后端 php 進一步處理文件。
簡單模擬了已下前端部分,并沒有寫后端 php。
分析問題:
1、 前端先做第一步判斷減輕服務器壓力,但是也容易被繞過,所以后端還是得判斷一次(也許可以優化法子?)
2、 但是并沒有賦予前端任何權利并沒有安全問題,壓力給到后端。
Code:
前端部分 js 代碼如下:
<body><div class="upload-container"><h2>上傳文件</h2><form action="upload.php" method="post" enctype="multipart/form-data"><input type="file" name="fileToUpload" id="file" onchange="check_upload(this.value)"><button type="submit">上傳文件</button></form></div>
</body><!-- 使用js來實現前端的文件格式過濾 -->
<script>//文件后綴白名單let list_write=['jpg','png','gif','jpeg','webp'];//文件上傳時發生改變觸發方法function check_upload(file_name){//取出后綴let idx=file_name.lastIndexOf('.');let val=file_name.substring(idx+1,file_name.length);if(list_write.indexOf(val)!=-1){console.log('文件格式無誤');//將文件發送后端……}else{//刷新網頁取消文件輸入location.reload(true);alert('文件格式有誤'); }}
</script>
打包器webpack
基本的目錄結構如下:
D:\VSCODE\WEBPACK-DEMO
│ package.json(版本控制及腳本配置)
│ webpack.config.js(配置文件)
│
├─dist(打包后的成品code)
├─node_modules(依賴包)
└─src(存自己寫的code)
???├─index.html
???└─index.js
接下來通過簡單使用來復習功能,并引入其作用。
開始之前先復習一下其概念:
Webpack 是一個現代 JavaScript 應用程序的靜態模塊打包工具。它分析項目結構,找到 JavaScript 模塊以及其他一些瀏覽器不能直接運行的擴展語言(如 Scss,TypeScript 等),并將其轉換和打包為合適的格式供瀏覽器使用。
然后使其使用與感悟:
就舉個最簡單的 js 方面的例子:一個html頁面可能需要引入非常多的 js 文件,不但太多了不好維護,也會導致訪問的速度變慢,為了解決這一問題,可以用打包器 webpack 將任意多個 js 文件打包成一個或幾個 js 文件。流程大致如下:
1、打包器分析 js 文件之間的依賴關系(通過import
/require
語句)
2、構建依賴圖
3、打包、優化、合并成一/幾個 JS 文件
一、 新建文件夾 ‘js’,存放兩個 js 文件
代碼分別如下:
function divide(a,b){return a-b;
}
export default divide;
export default function add(a,b){return a+b;
}
二、 在 src 目錄下新建一個 JS 文件用于聯系多個 JS 文件(上面兩)
import one from '../js/_1';
import two from '../js/_2';console.log(one(1,2))
console.log(two(1,2))
三、 配置 webpack.config.js 文件如下
const path = require('path');module.exports = {mode:"development",//開發模式// mode:"production" 生產模式entry: './src/index.js',//入口文件output: {filename: 'bundle.js',//結果文件path: path.resolve(__dirname, 'dist')//結果文件的位置},
}
知識點 |
1、 上面配置 code 中的 mode
????開發模式用于網站開發過程中,生產模式用于網站部署后。至于弄混會咋樣,如圖,源碼漏泄給瀏覽器
四、 執行打包命令
首先在
package.json
文件里添加下面代碼,然后移動終端的路徑到webpack根目錄下,運行命令npm run build
"scripts":{"build":"webpack"}
這里也貼上兩種模式產生的結果 JS 文件代價量的區別
生產模式code:
(()=>{"use strict";console.log(1-2),console.log(3)})();
開發模式code:
是的,1行和100行的區別
/** ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({/***/ "./js/_1.js":
/*!******************!*\!*** ./js/_1.js ***!\******************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction divide(a,b){\r\n return a-b;\r\n}\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (divide);\n\n//# sourceURL=webpack:///./js/_1.js?\n}");/***/ }),/***/ "./js/_2.js":
/*!******************!*\!*** ./js/_2.js ***!\******************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ add)\n/* harmony export */ });\nfunction add(a,b){\r\n return a+b;\r\n}\n\n//# sourceURL=webpack:///./js/_2.js?\n}");/***/ }),/***/ "./src/index.js":
/*!**********************!*\!*** ./src/index.js ***!\**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _js_1__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../js/_1 */ \"./js/_1.js\");\n/* harmony import */ var _js_2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../js/_2 */ \"./js/_2.js\");\n\r\n\r\n\r\nconsole.log((0,_js_1__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(1,2))\r\nconsole.log((0,_js_2__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(1,2))\n\n//# sourceURL=webpack:///./src/index.js?\n}");/***/ })/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
/******/
/******/ })()
;
express實現服務端
服務器,也就是訪問特定ip與端口會返回特定數據
由此
1、模擬網頁刷新(渲染特定網頁)
2、模擬網頁傳輸用戶名密碼需要連接數據庫并返回結果
3、依據get、post方式不同返回不同(路由)
由于是簡單模擬,所以都集合在了一個server.js
里,還有一個返回/渲染網頁用的html文件。
html 文件為渲染用登錄頁面,code:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>登錄頁面</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh;font-family: sans-serif;}.login-form {padding: 20px;border: 1px solid #ccc;border-radius: 8px;width: 300px;}.error-message {color: red;display: none;}</style>
</head>
<body><form action="http://127.0.0.1:3001/login" method="POST" ><h3>用戶登錄</h3><div><label for="username">用戶名:</label><input type="text" id="username" name="username" required></div><div><label for="password">密碼:</label><input type="password" id="password" name="password" required></div><input type="submit" value="登錄"></form>
</body>
</html>
server.js
文件code:
// 引入模塊
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
// 創建一個express應用
const app = express();
// 定義端口號
const port = 3001;
// 提供靜態文件服務
// app.use(express.static('public'));// 解析 application/x-www-form-urlencoded 數據
app.use(bodyParser.urlencoded({ extended: false }));// 初始頁面
app.get('/',(req, res) => {// res.send('GET請求成功!');//還可以渲染(返回)html文件!!res.sendFile(__dirname+"/html/login.html");
});// 1、get 方式傳輸表單數據
app.get('/login',(req, res) => {//參數獲取const u=req.query.username;const p=req.query.password;//連接數據庫……//判斷if(u=="admin" && p=="123456"){res.send("歡迎管理員!get");}else{res.send("閑雜人等不得入內!get");}
});
// 2、post 方式傳輸表單數據
app.post('/login',(req, res) => {//參數獲取const u=req.body.username;const p=req.body.password;//數據庫設置const connection = mysql.createConnection({host : 'localhost',user : 'root',password : 'password',database : 'user_all',port :'3307'});//連接數據庫connection.connect((error)=>{if(error){console.log("連接失敗");}else{console.log("連接成功");}})//語句let sentence='SELECT * FROM admin where username="'+u+'" and password="'+p+'"';console.log(sentence);connection.query(sentence, (error, results, fields)=>{if(error){console.log("數據庫連接失敗")}console.log(results);try{//判斷if(u==results[0]["username"] && p==results[0]["password"]){res.send("歡迎管理員!post");}else{res.send("閑雜人等不得入內!post");}}catch{console.log("語句有誤!");}});// //判斷// if(u=="admin" && p=="123456"){// res.send("歡迎管理員!post");// }else{// res.send("閑雜人等不得入內!post");// }
});// 啟動服務器并監聽指定端口
app.listen(port, () => {console.log(`Server is running on http://localhost:${port}`);
});
(如有不恰當的地方歡迎指正哦 ~o(●’?’●)o)
參考blogs:
【webpack超詳細教程,學webpack看這一篇就夠了!(上)】
【【Webpack】三種模式詳解】
【Webpack三種打包方式:(以下所有命令都是windows下執行的)】