昨天,把所有服務端的mock都實現:
上代碼:
"""
---------------------------------------------------------------------------------------
1.功能1:收集長鏈接并生成短鏈接
dag流程:收集長URL,并確認長URL有效,如果有效則生成短URL,并傳遞到后端服務器。
1-1 收集長URL: 通過在index.html 中設計一個表單,客戶輸入表單后,用requests.form 方法獲取表單內容
1-2 檢查長URL是否有效:通過checkurl(longurl)函數,當longurl 有效則返回1,否則返回0 【客戶端】
1-3 生成短URL:通過createshorturl(longurl)函數,從長url里面截取字段另外加上時間來生成一個短url 【客戶端】
1-4 傳遞到后端服務器:把長短URL的關系記錄到后端 【客戶端】 【服務端】
具體實現可以通過requests.post 方法,向對應的restful api 進行請求(備注1),傳遞jason字段(備注2)
備注1:這里指post 的url,指requsts.post 請求對應的Url,建議post的url要詳細到具體的接口,比如127.0.0.1:8008/api/shorturlcreate 接口,這樣后端服務器可以根據接口特性來進行相應的邏輯處理
備注2:制作字典,按照 dic1={短鏈:{"長鏈":長鏈,"訪問日期":"null","創建日期":date}} 創建
另外,requests.post 方式,選擇data=json 方式傳遞,json字段是對備注2里字典信息做字符串序列化的結果 json.dumps(dic1)
2.功能2:收集短鏈接做相關跳轉
dag流程:收集短url,如果短url存在,則接收服務端的redirect請求,跳轉到短URL對應的長URL鏈接上。
2-1 收集短url:通過在index.html設計一個表單,客戶輸入表單后,用requests.form方法獲取表單內容
2-2 檢查短url是否存在:通過checksurl(shorturl)函數,當shorturl有效則返回1,否則返回0 (服務端)
2-3 跳轉到長URL:通過jumpurl(shorturl)函數,請求到服務端。服務端先判斷短URL是否存在,如果存在則做redirect。
jumpurl函數設計:
1.訪問到后端服務器,requests.post(url/api/jump,""), 后端服務器根據URL具體的api來返回信息,返回值里包含了URL信息
2.服務端要構造返回的Header值,根據Location 參數 ,讓客戶瀏覽器跳轉到對應的長鏈URL中
3.功能3:請求某個短鏈的訪問信息,并進行展示:
dag流程:收集短url 對應的信息,如果短URL存在,則返回這個短URL被調度的次數等信息
3-1 在第2-3步,每次服務端指定后端做跳轉的時候,把短URL被訪問的時間做一個記錄。
服務端操作:
每次訪問短鏈的時候,對訪問情況做個統計:
3-1-1: {短url:訪問時間} 存入redis 另外一個表里。
3-2-2:對之前的 數據結構做個更新,主要是對 shorturl 的value做個update,訪問時間增加一行。
3-2 發起請求,通過requests.post() 函數,傳參數為 /api/statics ,到后端
收集后端返回的json字符串,查詢時間,短url,以及這個url的訪問列表,{date:[list],"shorturl",url, visittime:[list]}。
用json.loads() 把信息拿到,然后收集visittime的信息,
按照天的維度對visittime做一個圖像化。---作業。
redis 數據結構設計:
key:value
shorturl:{"對應的長鏈接":longurl,"訪問時間":[visitdate1,visitdate2],"創建時間":createdate}
把短鏈做為Key,把長鏈的信息、訪問時間,創建時間作為value,
---------------------------------------------------------------------------------------
"""
import redis
import re
import json
import time
import cgi
from redis import StrictRedis, ConnectionPool
from flask import Flask,jsonify,request
import requests
app=Flask(__name__)
def insert_into_redis(shorturl,longurl):
# 如果含義為插入,則做插入操作
pool=ConnectionPool(host='localhost', port=6379, db=0, decode_responses=True)
# redis 取出的結果默認是字節,我們可以設定 decode_responses=True 改成字符串。
r=StrictRedis(connection_pool=pool)
string=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
r.hset("shorttolong",shorturl, json.dumps({"longurl": longurl,"visittime": [], "creattime":string}))
r.hset("longtoshort",longurl,shorturl)
print("The value {0} is inserted".format(shorturl))
return 1
def check_if_exist(longurl):
pool=ConnectionPool(host='localhost', port=6379, db=0, decode_responses=True)
r=StrictRedis(connection_pool=pool)
# 判斷是否存在,如果存在則返回1
if r.hexists("longtoshort",longurl):
result=1
else:
result=0
return result
def get_longurl(shorturl):
pool=ConnectionPool(host='localhost', port=6379, db=0, decode_responses=True)
r=StrictRedis(connection_pool=pool)
# 判斷是否存在,如果存在則返回1
longurljson=r.hmget("shorttolong",shorturl)
longurl=json.loads(longurljson[0])["longurl"]
#print(longurljson)
#print(longurl)
return longurl
def update_jumptime(shorturl):
pool=ConnectionPool(host='localhost', port=6379, db=0, decode_responses=True)
r=StrictRedis(connection_pool=pool)
longurljson=r.hmget("shorttolong", shorturl)
dic1=json.loads(longurljson[0])
list1=dic1["visittime"]
print(list1)
string=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
list1.append(string)
dic1["visittime"]=list1
r.hset("shorttolong", shorturl, json.dumps(dic1))
print("info: update the visittime of the {0} success".format(shorturl))
return 1
def redirect_to_longurl(longurl):
redirect("https://"+longurl)
return 1
"""
0.判斷長鏈接是否已經存在
在用戶端進行創建的時候,要檢查長鏈接是否已經在服務端存在了,如果存在應該忽略。
如何確定服務端存在,通過post 接口來查詢。
檢查長URL是否有效:通過checkurl(longurl)函數,當longurl 已經存在,
返回json字段{'result':1},不存在則否則返回{'result':0}
"""
@app.route('/api/checkurl', methods=['POST'])
def check_url():
longurl=request.json['longurl']
result=check_if_exist(longurl)
print(result)
return jsonify({'result':result,"longurl":longurl}),200
"""
1.收集長鏈接生成短鏈接:
根據客戶端的post 請求,收集客戶端發送的shorturl以及longurl,把關聯關系插入到redis中
插入的時候,redis表中有兩個hash庫,
"shorttolong" 庫,結構為 shorturl:{"longurl":longurl,"visittime",{},"createtime":string}
"longtoshort" 庫,結構為 longurl:shorturl
"""
@app.route('/api/shorturlcreate',methods=['POST'])
def shorturl_create():
shorturl=request.json['shorturl']
longurl=request.json['longurl']
insert_into_redis(shorturl, longurl)
print("info: insert into redis {0}:{1} success".format(shorturl,longurl))
return jsonify({"info":"insert into redis "+longurl+shorturl+" pair succuss"})
"""
2.收集短鏈接做相關跳轉:
客戶端發出短鏈接請求,
2-1: 判斷短鏈接是否存在
2-2: 如果存在,則找到對應的長鏈接
2-3: 返回301 指令,并讓客戶端做跳轉
"""
@app.route('/api/shorturljump',methods=['POST'])
def shorturl_jump():
shorturl=request.json['shorturl']
# getlongurl mock
longurl=get_longurl(shorturl)
# 增加一個跳轉的時間,對他記錄。
# redis_update_jumptime(shorturl) mock
update_jumptime(shorturl)
# jumpto destination longurl,mock
print("info: jump to destination longurl {0} ".format(longurl))
#redirect_to_longurl(longurl)
return jsonify({"info": "jump to "+ longurl + " succuss"})
if __name__=='__main__':
app.run(host='0.0.0.0',port=8008,debug=True)
效果圖:
插入一個網站: longurl : www.163.com shorturl: 163
檢查網站是否存在:longurl :163
登錄redis后臺,查看相關信息:
做jump 操作,后臺會update 跳轉時間,并做redirect 動作,
看到visittime被udpate了
起html的錨點這個概念,你可能會感到會陌生,感覺自己沒有聽過。但是如果說起它的作用,你可能就恍然大悟了,就像你說起一個演員,可能不知道是誰,但是說起它演的一個角色可能立馬就知道那個人是誰了。
那么,什么是錨點呢?
錨點存在于html中,在默認情況下,可以快速的定位到指定元素,并將元素置于頁面最頂端。當然我們可以按照自己的需求來確定錨點的位置,不一定要讓其定位在頂部。現如今有無數多的頁面已經用上了錨點,比如Vue.js的官網,在我們點擊標題“Vue.js是什么”和標題“起步”的時候,標題都會自動移到頁面頂端。
錨點的使用
那接下來,我們就來看看幾種錨點的使用方法。
id定位
最基本的使用方法如下,當點擊<a>標簽時,頁面會相應的將該div內容置頂
錨點的id定位方法
name定位
除了id,還可以通過name進行定位,不過需要主要的是,如果采用name屬性進行定位的話,只適用于a標簽,類似于p標簽等都不支持。
錨點的name定位方法
javascript代碼進行定位
在原生的javascript中,有一個scrollIntoView()方法,可以實現頁面的錨點
javascript方法實現錨點
一個綜合的例子
講了三種實現方法后,接下來看一個實際運用的例子。首先是實際效果圖,在點擊左側欄時,頁面右邊會相應的顯示指定段落的內容
錨點的實際使用
首先看下html頁面的內容,左側的ul代碼
左側的ul代碼
右側的內容部分代碼
右側內容部分代碼
css部分的代碼
css部分的代碼
將上述的代碼寫在一個html文件中,便可實現左側欄點擊,右側欄顯示相應內容的效果。
特殊情況
在實際項目中,我們總會遇到這樣一種情況,在頁面頂部有固定頭內容的時候,如果直接使用上述方法,會得不到想要的效果
直接使用錨點的效果圖
通過該圖可以看出,第三段內容的標題被遮住了,實際應該往下再顯示一點
那么,我們該怎么解決這個問題呢?在這里我想到了兩種方法,第一種是在每個內容div上加一個隱藏的p元素,給p元素一個定高,再向上偏移,這種方法會導致頁面出現很多個多余的p元素,不推薦使用。
第二種是利用偽元素,偽元素可以占用實際的高度,這是推薦使用的方法
偽元素的樣式
通過給h3標簽添加偽元素樣式,可完美解決這個問題,效果圖如下
使用偽元素后的效果圖
總結
今天的內容你會了么?如果還沒有掌握的話,可以按照文章中的代碼,進行實踐,代碼總是要多敲才更容易理解。
如果喜歡的話,記得關注小編噢,小編后續會堅持出更多技術性的文章,如果有任何問題,也歡迎提問,小編都會盡力解答的。
indow:典型情況下, 瀏覽器會為每一個打開的html創建對應的window對象, 如果這個文檔包含了多個框架(), 則瀏覽器會為原始文檔建立一個window對象, 再為每個框架創建額外的window對象。
可以再當前窗口中直接使用window的全部屬性、方法和集合, 即不需要在前面附加計算結果為當前window對象的表達式。雖然window可以省略, 但是為了方便閱讀以及避免一些漏洞, 一般都使用這個關鍵字。
location:該對象包含當前url信息, 擁有多個屬性。默認屬性為 location.href,表示整個url, 即如果設置location="https://www.xxxxxx.com/", 則等同于location.href="https://www.xxxxxx.com/"。
第一種:超鏈接
<a href="https://www.xxxxxx.com/" title="百度">Welcome</a>
等效于
//在同當前窗口中打開窗口
window.location.href="https://www.xxxxxx.com/";
第二種:超鏈接
<a href="https://www.xxxxxx.com/" title="百度" target="_blank">Welcome</a>
等效于
//在另外新建窗口中打開窗口
window.open("https://www.xxxxxx.com/");
第3種:window.navigate("https://www.xxxxxx.com/"); //只對ie瀏覽器有效, 其他瀏覽器無效, 不建議使用。
第4種:
self.location='https://www.xxxxxx.com/'; //self:當前窗口對象
第5種:
top.location='https://www.xxxxxx.com/'; //top父窗口對象 頁面跳出框架
第4種和第5種聯合使用, 可以防止別人用iframe等框架引用你的頁面。
//反之iframe等框架引用
if(top.location.href !=self.location.href){
window.location.href="https://www.xxxxxx.com/";
}
第6種:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。