Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
電腦報在線】絕大多數(shù)投資者只關(guān)心P2P理財網(wǎng)站的回報是不是高、資金安全能不能得到保障,極少會有人注意P2P理財網(wǎng)站的有沒有安全隱患,會不會給自己帶來潛在的安全威脅。可P2P理財網(wǎng)站的安全隱患一直層出不窮,一年因為黑客事件而關(guān)停的平臺超過100家。這不,最近又有一個P2P理財網(wǎng)站爆出奇葩漏洞了……
技術(shù)分析
白帽子 牛小帥:無意中看到某P2P理財網(wǎng)站的廣告,就順手走了一個安全監(jiān)測。注冊一個賬號后,直接定位到找回密碼頁面http://www.***n***u.com/member/common/lookforpwd.html,頁面看著簡潔,實際存在漏洞——在這里動用抓包類黑客工具,就可以看到賬號和密碼,reg_phone后面的數(shù)字就是賬號,checkcode后面的數(shù)字就是密碼,通過這個方法就可以竄改任意用戶的密碼。
最奇葩的,驗證碼是擺設(shè),無論對錯都可以竄改,這就意味著只需要注冊過的用戶的密碼全部都可以竄改。
無論驗證碼對錯都可以修改
讀者點(diǎn)評
@雪中帶刀行:對了,的確有P2P理財網(wǎng)站以漏洞的名義敲詐,還有被流量攻擊的,我記得以前人人貸就遭過,才宣布獲得1.3億美元的投資,兩小時不到就被黑客盯上了,一口氣發(fā)動了7GB的流量攻擊,導(dǎo)致我們訪問人人貸的都困難。
@蒼山獨(dú)行:這個方法可以看到用戶的賬戶余額,但無法直接盜取錢財,怕就怕?lián)p人不利己的黑客亂買理財產(chǎn)品,那就悲劇了。
篇文章JavaScript基礎(chǔ)——你真的清楚JavaScript是什么嗎?,我們明白了JavaScript是一個單線程、非阻塞、異步、解釋性語言,清楚了什么是單線程、進(jìn)程、阻塞、調(diào)用堆棧、異步回調(diào)、任務(wù)循環(huán)等感念,沒看的或者不清楚的建議點(diǎn)擊《JavaScript基礎(chǔ)——你真的清楚JavaScript是什么嗎?再看一遍,只有理解了,才能輕松閱讀理解本篇文章內(nèi)容。
什么是callback?
JavaScript 是單線程工作,這意味著兩段腳本不能同時運(yùn)行,而是必須一個接一個地運(yùn)行。我們?nèi)祟愂嵌嗑€程工作。您可以使用多個手指打字,可以一邊開車一邊與人交談。唯一一個會妨礙我們的是打噴嚏,因為當(dāng)我們打噴嚏的時候,所有當(dāng)前進(jìn)行的活動都必須暫停。這真是非常討厭,尤其是當(dāng)您在開車并想與人交談時。您可不想編寫像打噴嚏似的代碼。JavaScript由于單線程限制,防止阻塞,只能通過異步函數(shù)的調(diào)用方式,把需要延遲處理的事件放入事件循環(huán)隊列。到目前為止,回調(diào)是編寫和處理JavaScript程序異步邏輯的最常用方式。說了這么多,既然回調(diào)這么重要,到底什么是回調(diào)(callback)呢?
簡單的定義:回調(diào)就是一個在另外一個函數(shù)執(zhí)行完后要執(zhí)行的函數(shù)
復(fù)雜的定義:在JavaScript中,函數(shù)是對象。因此函數(shù)可以將函數(shù)作為參數(shù),并且可以由其他函數(shù)進(jìn)行返回。執(zhí)行此操作的函數(shù)稱為高階函數(shù)。任何作為參數(shù)傳遞的函數(shù)都稱為回調(diào)函數(shù)。
為什么需要回調(diào)?
開篇已經(jīng)介紹了JavaScript是單線程的,需要通回調(diào)函數(shù)處理異步相關(guān)的邏輯,理論還是過于生硬,我們還是來看段代碼吧:
function first(){ console.log(1); } function second(){ console.log(2); } first(); second();
正如你所料,先執(zhí)行first函數(shù),再執(zhí)行second函數(shù),控制臺將輸出以下內(nèi)容:
1 2
目前看來沒什么問題,如果first()函數(shù)中含有某種無法立即執(zhí)行的函數(shù)呢?例如,我們必須發(fā)送請求然后等待結(jié)果響應(yīng)的API請求?為了模擬API請求,我們可以使用setTimeout函數(shù)模擬。我們將函數(shù)延遲500毫秒來模擬請求,我們更改后代碼如下:
function first(){ // Simulate a code delay setTimeout( function(){ console.log(1); }, 500 ); } function second(){ console.log(2); } first(); second();
我們將 console.log(1) 延遲500毫秒輸出,這段代碼會怎么輸出呢?
2 1
我們希望的順序先執(zhí)行first,再執(zhí)行second,但是由于JavaScript是異步的,所有的延遲處理都要放入循環(huán)隊列里,因此事與愿違,不能按照我們的希望順序輸出。如果希望這段代碼按照我們的意愿輸出,我們可以使用回調(diào)函數(shù),確保某些代碼執(zhí)行完了,在循序執(zhí)行另外一段代碼。
創(chuàng)建回調(diào)
說了這么多,讓我們創(chuàng)建一個簡單的回調(diào)!
我們打開編輯器,先輸入如下代碼:
function doHomework(subject) { alert(`Starting my ${subject} homework.`); }
上面我們創(chuàng)建了doHomeWork的函數(shù),我們接受一個變量,通過控制臺調(diào)用,將得到下面的提示:
doHomework('math'); // Alerts: Starting my math homework.
接著,我們開始添加回調(diào),在doHomework函數(shù)中添加一個參數(shù)callback,然后在第二個參數(shù)中回調(diào)我們定義的函數(shù)。代碼如下:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } doHomework('math', function() { alert('Finished my homework'); });
正如你希望的,我們在控制臺里運(yùn)行上述代碼,將會受到兩個連續(xù)的alert,Starting my math homework,然后彈出 Finished my homework。
但是回調(diào)函數(shù)并不是非得在調(diào)用函數(shù)中定義,我們可以單獨(dú)定義,修改后的代碼如下:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } function alertFinished(){ alert('Finished my homework'); } doHomework('math', alertFinished);
此示例的輸出結(jié)果和上段代碼的結(jié)果一致,我們實現(xiàn)了在doHomework函數(shù)中調(diào)用alertFinished,實現(xiàn)了函數(shù)作為參數(shù)進(jìn)行傳遞,實現(xiàn)了回調(diào)函數(shù)的創(chuàng)建。
用回調(diào)寫一段真實業(yè)務(wù)場景的代碼!
例如我們有一個需求,用NodeJs實現(xiàn)從論壇帖子列表中顯示其中的一個帖子的信息及留言列表信息,代碼如下:
DB/posts.json(帖子列表數(shù)據(jù))
[ { "id": "001", "title": "Greeting", "text": "Hello World", "author": "Jane Doe" }, { "id": "002", "title": "JavaScript 101", "text": "The fundamentals of programming.", "author": "Alberta Williams" }, { "id": "003", "title": "Async Programming", "text": "Callbacks, Promises and Async/Await.", "author": "Alberta Williams" } ]
DB/comments.json(評論列表)
[ { "id": "phx732", "postId": "003", "text": "I don't get this callback stuff." }, { "id": "avj9438", "postId": "003", "text": "This is really useful info." }, { "id": "gnk368", "postId": "001", "text": "This is a test comment." } ]
Index.js
const fs = require('fs'); const path = require('path'); const postsUrl = path.join(__dirname, 'db/posts.json'); const commentsUrl = path.join(__dirname, 'db/comments.json'); //return the data from our file function loadCollection(url, callback) { fs.readFile(url, 'utf8', function(error, data) { if (error) { console.log(error); } else { return callback(JSON.parse(data)); } }); } //return an object by id function getRecord(collection, id, callback) { var collectobj=collection.find(function(element){ return element.id == id; }); callback(collectobj); return collectobj; } //return an array of comments for a post function getCommentsByPost(comments, postId) { return comments.filter(function(comment){ return comment.postId == postId; }); } loadCollection(postsUrl, function(posts){ loadCollection(commentsUrl, function(comments){ getRecord(posts, "001", function(post){ const postComments = getCommentsByPost(comments, post.id); console.log(post); console.log(postComments); }); }); });
大家請注意,我們在loadCollection函數(shù)中我們沒有使用try/catch,使用的是if/else,因為catch無法從readFile方法中獲取錯誤。上述代碼還需要完善,我沒有包含任何錯誤處理。如果在任何步驟中發(fā)生錯誤,程序?qū)o法繼續(xù)。
錯誤處理是很重要的事情,我們寫代碼時要嚴(yán)格對待,比如我們要編寫一個用戶登錄的功能。涉及從網(wǎng)頁表單里獲取用戶名和密碼,查詢我們的數(shù)據(jù)庫,確認(rèn)用戶信息是否正確,驗證通過后,將用戶引導(dǎo)到用戶中心頁面。如果用戶名密碼格式不正確,用戶名密碼不正確,我們應(yīng)該將錯誤信息返回給用戶,并引導(dǎo)用戶重新登錄。
總結(jié)
很好!我們一起把回調(diào)的內(nèi)容學(xué)完了,理解了什么是回調(diào),異步編程是我們的代碼中使用的一種方法,用于推遲事件以便以后執(zhí)行。當(dāng)您處理異步任務(wù)時,回調(diào)是一種解決方案,以便它們按順序執(zhí)行。
如果我們有多個任務(wù)依賴于前幾個任務(wù)的結(jié)果,那我們就要使用多個嵌套回調(diào),但是就會引發(fā)“回調(diào)地域”(過多的回調(diào)嵌套會使得代碼變得難以理解與維護(hù)),還好Promise解決了“回調(diào)地獄”的問題,讓我們以同步的方式編寫代碼,小編將會再下篇文章里進(jìn)行詳細(xì)介紹,敬請期待!
更多精彩內(nèi)容,請微信關(guān)注”前端達(dá)人”公眾號!
篇文章《JavaScript基礎(chǔ)——你真的了解JavaScript嗎?》,我們明白了JavaScript是一個單線程、非阻塞、異步、解釋性語言,清楚了什么是單線程、進(jìn)程、阻塞、調(diào)用堆棧、異步回調(diào)、任務(wù)循環(huán)等概念,沒看的或者不清楚的建議點(diǎn)擊《JavaScript基礎(chǔ)——你真的了解JavaScript嗎?》再看一遍,只有理解了,才能輕松閱讀理解本篇文章內(nèi)容。
JavaScript 是單線程工作,這意味著兩段腳本不能同時運(yùn)行,而是必須一個接一個地運(yùn)行。我們?nèi)祟愂嵌嗑€程工作。您可以使用多個手指打字,可以一邊開車一邊與人交談。唯一一個會妨礙我們的是打噴嚏,因為當(dāng)我們打噴嚏的時候,所有當(dāng)前進(jìn)行的活動都必須暫停。這真是非常討厭,尤其是當(dāng)您在開車并想與人交談時。您可不想編寫像打噴嚏似的代碼。JavaScript由于單線程限制,防止阻塞,只能通過異步函數(shù)的調(diào)用方式,把需要延遲處理的事件放入事件循環(huán)隊列。到目前為止,回調(diào)是編寫和處理JavaScript程序異步邏輯的最常用方式。說了這么多,既然回調(diào)這么重要,到底什么是回調(diào)(callback)呢?
簡單的定義:回調(diào)就是一個在另外一個函數(shù)執(zhí)行完后要執(zhí)行的函數(shù)
復(fù)雜的定義:在JavaScript中,函數(shù)是對象。因此函數(shù)可以將函數(shù)作為參數(shù),并且可以由其他函數(shù)進(jìn)行返回。執(zhí)行此操作的函數(shù)稱為高階函數(shù)。任何作為參數(shù)傳遞的函數(shù)都稱為回調(diào)函數(shù)。
開篇已經(jīng)介紹了JavaScript是單線程的,需要通回調(diào)函數(shù)處理異步相關(guān)的邏輯,理論還是過于生硬,我們還是來看段代碼吧:
function first(){ console.log(1);} function second(){ console.log(2);} first(); second();
正如你所料,先執(zhí)行first函數(shù),再執(zhí)行second函數(shù),控制臺將輸出以下內(nèi)容:
1 2
目前看來沒什么問題,如果first()函數(shù)中含有某種無法立即執(zhí)行的函數(shù)呢?例如,我們必須發(fā)送請求然后等待結(jié)果響應(yīng)的API請求?為了模擬API請求,我們可以使用setTimeout函數(shù)模擬。我們將函數(shù)延遲500毫秒來模擬請求,我們更改后代碼如下:
function first(){ // Simulate a code delay setTimeout( function(){ console.log(1); }, 500 ); } function second(){ console.log(2);} first(); second();
我們將 console.log(1) 延遲500毫秒輸出,這段代碼會怎么輸出呢?
2 1
我們希望的順序先執(zhí)行first,再執(zhí)行second,但是由于JavaScript是異步的,所有的延遲處理都要放入循環(huán)隊列里,因此事與愿違,不能按照我們的希望順序輸出。如果希望這段代碼按照我們的意愿輸出,我們可以使用回調(diào)函數(shù),確保某些代碼執(zhí)行完了,再執(zhí)行另外一段代碼。
說了這么多,讓我們創(chuàng)建一個簡單的回調(diào)!
我們打開編輯器,先輸入如下代碼:
function doHomework(subject) { alert(`Starting my ${subject} homework.`); }
上面我們創(chuàng)建了doHomeWork的函數(shù),我們接受一個變量,通過控制臺調(diào)用,將得到下面的提示:
doHomework('math'); // Alerts: Starting my math homework.
接著,我們開始添加回調(diào),在doHomework函數(shù)中添加一個參數(shù)callback,然后在第二個參數(shù)中回調(diào)我們定義的函數(shù)。代碼如下:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } doHomework('math', function() { alert('Finished my homework'); });
正如你希望的,我們在控制臺里運(yùn)行上述代碼,將會受到兩個連續(xù)的alert,Starting my math homework,然后彈出 Finished my homework。
但是回調(diào)函數(shù)并不是非得在調(diào)用函數(shù)中定義,我們可以單獨(dú)定義,修改后的代碼如下:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } function alertFinished(){ alert('Finished my homework'); } doHomework('math', alertFinished);
此示例的輸出結(jié)果和上段代碼的結(jié)果一致,我們實現(xiàn)了在doHomework函數(shù)中調(diào)用alertFinished,實現(xiàn)了函數(shù)作為參數(shù)進(jìn)行傳遞,實現(xiàn)了回調(diào)函數(shù)的創(chuàng)建。
例如我們有一個需求,用NodeJs實現(xiàn)從論壇帖子列表數(shù)據(jù)中顯示其中的一個帖子的信息及留言列表信息,代碼如下:
DB/posts.json(帖子列表數(shù)據(jù))
[ { "id": "001", "title": "Greeting", "text": "Hello World", "author": "Jane Doe" }, { "id": "002", "title": "JavaScript 101", "text": "The fundamentals of programming.", "author": "Alberta Williams" }, { "id": "003", "title": "Async Programming", "text": "Callbacks, Promises and Async/Await.", "author": "Alberta Williams" } ]
DB/comments.json(評論列表)
[ { "id": "phx732", "postId": "003", "text": "I don't get this callback stuff." }, { "id": "avj9438", "postId": "003", "text": "This is really useful info." }, { "id": "gnk368", "postId": "001", "text": "This is a test comment." } ]
Index.js
大家請注意,在loadCollection函數(shù)中小編沒有使用try/catch捕捉異常,使用的是if/else,因為catch無法從readFile方法中獲取異常。上述代碼還需要完善,我沒有包含任何錯誤處理。如果在任何步驟中發(fā)生錯誤,程序?qū)o法繼續(xù)。
錯誤處理是很重要的事情,我們寫代碼時要認(rèn)證嚴(yán)格對待,比如我們要編寫一個用戶登錄的功能。涉及從網(wǎng)頁表單里獲取用戶名和密碼,查詢我們的數(shù)據(jù)庫,確認(rèn)用戶信息是否正確,驗證通過后,將用戶引導(dǎo)到用戶中心頁面。如果用戶名密碼格式不正確,用戶名密碼不正確,我們應(yīng)該將錯誤信息返回給用戶,并引導(dǎo)用戶重新登錄。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。