Day21-Cookie
1. Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。例如在某个网站上保存了用户名和密码,3个月内免登陆。如果你换台电脑或者浏览器的话,则需要重新登录。就此说明cookie是保存在客户端浏览器上的一个文件。
2.实例---基于cookie实现用户信息验证
当用户名和密码都正确的时候,才跳转到index页面。否则就停留在login.html页面。
2.1 在setting中注释掉下面一句,防止报错
2.2 在urls.py中写路由对应关系
2.3 views.py写后端
dic
=
user_info.get(u)
#如果获取到了,表明用户是存在的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from django.shortcuts import render,HttpResponse,redirect from django.urls import reverse # Create your views here. user_info = { 'dachengzi' :{ 'pwd' : "123123" }, 'kanbazi' :{ 'pwd' : "kkkkkkk" }, } def login(request): if request.method = = 'GET' : return render(request, 'login.html' ) if request.method = = 'POST' : u = request.POST.get( 'username' ) p = request.POST.get( 'pwd' ) dic = user_info.get(u) if not dic: return render(request, 'login.html' ) if dic[ 'pwd' ] = = p: res = redirect( '/index/' ) res.set_cookie( 'username111' ,u) return res else : return render(request, 'login.html' ) def index(request): #获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) if not v: return redirect(request, '/login/' ) return render(request, 'index.html' ,{ 'current_user' :v}) |
2.4 写前端 index.html
1 2 3 4 5 6 7 8 9 10 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < h1 >欢迎登录:{{current_user}}</ h1 > </ body > </ html > |
2.4 写前端 login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < form action="/login/" method="POST"> < input type="text" name="username" placeholder="用户名"/> < input type="password" name="pwd" placeholder="密码"/> < input type="submit"/> </ form > </ body > </ html > |
2.5 效果
没有登录之前,是无法访问index页面的。
只有先从login页面登录了以后,才能跳转到index页面。
3. 在Django里面给cookie提供了一些额外的功能。
request.COOKIES-------表示用户发来数据的时候,它里面带的所携带的所有cookie信息。。。从请求中获取cookie
1 2 3 4 5 | def cookie(request): #用户发来请求时,它里面所携带的所有的cookie信息 request.COOKIES request.COOKIES['username111'] request.COOKIES.get('username111') |
设置cookie 键-值对
response.set_cookie('key','value')
1 2 3 4 5 6 7 8 9 10 | def cookie(request): #用户发来请求时,它里面所携带的所有的cookie信息 request.COOKIES request.COOKIES['username111'] request.COOKIES.get('username111')< br > response=render(request,'index.html') #通过render,redirect把内容返回给浏览器 response=redirect('/index/') #设置cookie,关闭浏览器后就失效< br > response.set_cookie('key','value') #还可以设置新的cookie 键-值对,也一并返回给浏览器< br > return response #里面不仅包含了内容,还包含了cookie的键-值对。 |
4. 默认情况下,关闭浏览器后,cookie就失效了,需要重新登录了。通过下面几种方法可以设置失效时间。
设置用户名和密码的失效时间-方法1,max_age=None
--------res.set_cookie('username111',u,max_age=10) 设置失效时间为10秒
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171017122333756-1788694238.png)
效果:10秒之后,用户名和密码就失效了,从index自动倒退回到login界面,需要重新登录了。
5. 设置用户名和密码的失效时间-方法2,expires=None
import datetime
current_date=datetime.datetime.utcnow()
current_daate=current_date+datetime.timedelta(seconds=5)
response.set_cookie('username111', "value", expires=current_date)
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171019152755521-394892530.png)
6. 其它属性
设置cookie的生效路: ---path='/',意思是在所有的url中都生效。path='/index' 指只在index页面有效。
生效的域名: domain=None
https传输: secure=False
httponly: 只支持http传输,在JS前端是无法获取的,没有安全不安全一说。示例如下:
设置2个cookie,其中1个有httponly=True属性,对比看效果
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171017144812318-761312989.png)
在页面上访问的时候,看到了2个cookie
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171017144907459-1760700004.png)
但是在前端却获取不到
7. 增加2个月内免登陆的功能,自己完成。把2个月换算成秒,添加到max_age=XXX里面就可以了。
注销的本质就是把cookie清除掉。
8. 完善实例,基于cookie实现定制显示数据条数
8.1----cookie在服务器端能读能写,在客户端也是能读能写的。
8.2----------jQuery有个插件叫jQuery-cookie,通过这个插件可以直接去浏览器上去操作cookie了。
从官网下载插件http://plugins.jquery.com/cookie/
8.3 用实例来验证,浏览器端确实可以获取到per_page_count这个值。
user_list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > < style > .pagination .page{ display:inline-block; padding:5px; background-color:cyan; margin:5px; } .pagination .page.active{ background-color:brown; color:white; } </ style > </ head > < body > < ul > {% for item in li %} {% include 'li.html' %} {%endfor%} </ ul > < div > 请选择每页显示条数 < select id="ps" onchange="changePageSize(this)"> < option value="10">10</ option > < option value="30">30</ option > < option value="50">50</ option > < option value="100">100</ option > </ select > </ div > < div class="pagination"> {{page_str}} </ div > < script src="/static/jquery-1.12.4.js"></ script > < script src="/static/jquery.cookie.js"></ script > < script > function changePageSize(ths){ var v=$(ths).val(); console.log(v); $.cookie('per_page_count',v); } </ script > </ body > </ html > |
在Console中也可以看到这个效果。
8.4 服务器端从客户端传过来的cookie中获取到这个值。并且在实例化的时候,把它传递给类。
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | from django.shortcuts import render,HttpResponse,redirect from utils import pagination from django.urls import reverse # Create your views here. LIST = [] for i in range ( 1000 ): LIST .append(i) def user_list(request): current_page = request.GET.get( 'p' ) current_page = int (current_page) val = request.COOKIES.get( 'per_page_count' ) print (val) val = int (val) page_obj = pagination.Page(current_page, len ( LIST ),val) data = LIST [page_obj.start:page_obj.end] page_str = page_obj.page_str( "/user_list/" ) return render(request, 'user_list.html' ,{ 'data' :data, 'page_str' :page_str}) user_info = { 'dachengzi' : { 'pwd' : "123123" }, 'kanbazi' : { 'pwd' : "kkkkkkk" }, } def login(request): if request.method = = 'GET' : return render(request, 'login.html' ) if request.method = = 'POST' : u = request.POST.get( 'username' ) p = request.POST.get( 'pwd' ) dic = user_info.get(u) if not dic: return render(request, 'login.html' ) if dic[ 'pwd' ] = = p: res = redirect( '/index/' ) res.set_cookie( 'username111' , u) return res else : return render(request, 'login.html' ) def index(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) if not v: return redirect(request, '/login/' ) return render(request, 'index.html' , { 'current_user' : v}) |
8.5 完善功能。用户选中每页显示多少条,浏览器上就显示多少条。
代码修改如下:
8.6 完善功能,指定生效的url路径
var v=$.cookie('per_page_count',{'path':"/user_list/"}); 指定路径
9. 至此,程序粘贴如下:
urls.py
1 2 3 4 5 6 7 8 9 10 | from django.conf.urls import url from django.contrib import admin from app_ch import views urlpatterns = [ url(r '^admin/' , admin.site.urls), url(r '^user_list/$' , views.user_list), url(r '^login' , views.login), url(r '^index' , views.index), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | from django.shortcuts import render,HttpResponse,redirect from utils import pagination from django.urls import reverse # Create your views here. LIST = [] for i in range ( 1000 ): LIST .append(i) def user_list(request): current_page = request.GET.get( 'p' ) current_page = int (current_page) val = request.COOKIES.get( 'per_page_count' ) print (val) val = int (val) page_obj = pagination.Page(current_page, len ( LIST ),val) data = LIST [page_obj.start:page_obj.end] page_str = page_obj.page_str( "/user_list/" ) return render(request, 'user_list.html' ,{ 'data' :data, 'page_str' :page_str}) user_info = { 'dachengzi' : { 'pwd' : "123123" }, 'kanbazi' : { 'pwd' : "kkkkkkk" }, } def login(request): if request.method = = 'GET' : return render(request, 'login.html' ) if request.method = = 'POST' : u = request.POST.get( 'username' ) p = request.POST.get( 'pwd' ) dic = user_info.get(u) if not dic: return render(request, 'login.html' ) if dic[ 'pwd' ] = = p: res = redirect( '/index/' ) res.set_cookie( 'username111' , u) return res else : return render(request, 'login.html' ) def index(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) if not v: return redirect(request, '/login/' ) return render(request, 'index.html' , { 'current_user' : v}) |
pagination.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | from django.utils.safestring import mark_safe class Page: def __init__( self ,current_page,data_count,per_page_count = 10 ,pager_num = 7 ): self .current_page = current_page self .data_count = data_count self .per_page_count = per_page_count self .pager_num = pager_num @property def start( self ): return ( self .current_page - 1 ) * self .per_page_count @property def end( self ): return self .current_page * self .per_page_count @property def total_count( self ): v, y = divmod ( self .data_count, self .per_page_count) if y: v = v + 1 return v def page_str( self ,base_url): page_list = [] if self .total_count < self .pager_num: start_index = 1 end_index = self .total_count + 1 else : if self .current_page < = ( self .pager_num + 1 ) / 2 : start_index = 1 end_index = self .pager_num + 1 else : start_index = self .current_page - ( self .pager_num - 1 ) / 2 end_index = self .current_page + ( self .pager_num + 1 ) / 2 if ( self .current_page + ( self .pager_num - 1 ) / 2 ) > self .total_count: end_index = self .total_count + 1 start_index = self .total_count - self .pager_num + 1 if self .current_page = = 1 : prev = '<a class="page" href="javascript:void(0)">上一页</a>' else : prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self .current_page - 1 ) page_list.append(prev) for i in range ( int (start_index), int (end_index)): if i = = self .current_page: temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url,i, i) else : temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url,i, i) page_list.append(temp) if self .current_page = = self .total_count: nex = '<a class="page" href="javascript:void(0);">下一页</a>' else : nex = '<a class="page" href=%s?p=%s>下一页</a>' % (base_url, self .current_page + 1 ) page_list.append(nex) jump = ''' <input type='text'/><a onclick='jumpTo(this,"%s?p=");'>Go</a> <script> function jumpTo(ths,base){ var val=ths.previousSibling.value; location.href=base+val; } </script> ''' % (base_url) page_list.append(jump) page_str = mark_safe("".join(page_list)) return page_str |
user_list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > < style > .pagination .page{ display:inline-block; padding:5px; background-color:cyan; margin:5px; } .pagination .page.active{ background-color:brown; color:white; } </ style > </ head > < body > < ul > {% for i in data%} < li >{{i}}</ li > {% endfor %} </ ul > < div > 选择每页显示的条数: < select id="ps" onchange="changePageSize(this)"> < option value="10">10</ option > < option value="30">30</ option > < option value="50">50</ option > </ select > </ div > < div class="pagination"> {{page_str}} </ div > < script src="/static/jquery-1.12.4.js"></ script > < script src="/static/jquery.cookie.js"></ script > < script > $(function(){ var v=$.cookie('per_page_count',{'path':"/user_list/"}); $('#ps').val(v); }); function changePageSize(ths){ var v=$(ths).val(); $.cookie('per_page_count',v,{'path':"/user_list/"}); location.reload(); } </ script > </ body > </ html > |
login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < form action="/login/" method="POST"> < input type="text" name="username" placeholder="用户名"/> < input type="password" name="pwd" placeholder="密码"/> < input type="submit"/> </ form > </ body > </ html > |
index.html
1 2 3 4 5 6 7 8 9 10 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >Title</ title > </ head > < body > < h1 >欢迎登录:{{current_user}}</ h1 > </ body > </ html > |
10. 带签名的cookie
-------明文:
获取cookie: request.COOKIES.get('......')
设置cookie: response.set_cookie(.....)
--------密文:
加密解密如下,注意盐要对应,否则解密会不成功。
obj=HttpResponse('s') #返回给客户端的数据
obj.set_signed_cookie('username',"kangbazi",salt='XXX') 通过XXX这个字符串,对cookie的内容进行加密。
request.get_signed_cookie('username',salt="XXX") 服务器端获取得时候,需要解密。
11. 用装饰器实现用户验证
假设这里不仅有index页面需要验证,然后还有一个order页面也需要验证。我们尝试用装饰器来实现。
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020090618146-131235016.png)
新建1个order页面,用FBV装饰器来实现。
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020091441974-2143435129.png)
用另外一种方法CBV实现
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020092743287-1529812819.png)
现在还没有登录,尝试用get访问的时候,效果如下:
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020092921443-261152949.png)
在dispatch方法执行完了以后,才执行下面的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | from django.shortcuts import render,HttpResponse,redirect from utils import pagination from django.urls import reverse # Create your views here. LIST = [] for i in range ( 1000 ): LIST .append(i) def user_list(request): current_page = request.GET.get( 'p' ) current_page = int (current_page) val = request.COOKIES.get( 'per_page_count' ) print (val) val = int (val) page_obj = pagination.Page(current_page, len ( LIST ),val) data = LIST [page_obj.start:page_obj.end] page_str = page_obj.page_str( "/user_list/" ) return render(request, 'user_list.html' ,{ 'data' :data, 'page_str' :page_str}) user_info = { 'dachengzi' : { 'pwd' : "123123" }, 'kanbazi' : { 'pwd' : "kkkkkkk" }, } def login(request): if request.method = = 'GET' : return render(request, 'login.html' ) if request.method = = 'POST' : u = request.POST.get( 'username' ) p = request.POST.get( 'pwd' ) dic = user_info.get(u) if not dic: return render(request, 'login.html' ) if dic[ 'pwd' ] = = p: res = redirect( '/index/' ) res.set_cookie( 'username111' , u) return res else : return render(request, 'login.html' ) def auth(func): def inner(request, * args, * * kwargs): v = request.COOKIES.get( 'username111' ) if not v: return redirect(request, '/login/' ) return func(request, * args, * * kwargs) return inner @auth def index(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) from django import views from django.utils.decorators import method_decorator class Order(views.View): @method_decorator (auth) def dispatch( self ,request, * args, * * kwargs): return super (Order, self ).dispatch(request, * args, * * kwargs) def get( self ,request): v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) def post( self ,request): v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) def order(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) |
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020093820802-1025943963.png)
可以更优化,把装饰器写到类的上面。
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020094023724-1539229006.png)
FBV和CBV两种方法实现装饰器的比较
![](https://images2017.cnblogs.com/blog/1200823/201710/1200823-20171020094254584-1420937661.png)
至此程序如下:
urls.py
1 2 3 4 5 6 7 8 9 10 11 | from django.conf.urls import url from django.contrib import admin from app_ch import views urlpatterns = [ url(r '^admin/' , admin.site.urls), url(r '^user_list/$' , views.user_list), url(r '^login' , views.login), url(r '^index' , views.index), url(r '^order' , views.Order.as_view()), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | from django.shortcuts import render,HttpResponse,redirect from utils import pagination from django.urls import reverse # Create your views here. LIST = [] for i in range ( 1000 ): LIST .append(i) def user_list(request): current_page = request.GET.get( 'p' ) current_page = int (current_page) val = request.COOKIES.get( 'per_page_count' ) print (val) val = int (val) page_obj = pagination.Page(current_page, len ( LIST ),val) data = LIST [page_obj.start:page_obj.end] page_str = page_obj.page_str( "/user_list/" ) return render(request, 'user_list.html' ,{ 'data' :data, 'page_str' :page_str}) user_info = { 'dachengzi' : { 'pwd' : "123123" }, 'kanbazi' : { 'pwd' : "kkkkkkk" }, } def login(request): if request.method = = 'GET' : return render(request, 'login.html' ) if request.method = = 'POST' : u = request.POST.get( 'username' ) p = request.POST.get( 'pwd' ) dic = user_info.get(u) if not dic: return render(request, 'login.html' ) if dic[ 'pwd' ] = = p: res = redirect( '/index/' ) res.set_cookie( 'username111' , u) return res else : return render(request, 'login.html' ) def auth(func): def inner(request, * args, * * kwargs): v = request.COOKIES.get( 'username111' ) if not v: return redirect(request, '/login/' ) return func(request, * args, * * kwargs) return inner @auth def index(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) from django import views from django.utils.decorators import method_decorator @method_decorator (auth,name = 'dispatch' ) class Order(views.View): def get( self ,request): v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) def post( self ,request): v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) def order(request): # 获取当前已经登录的用户名字 v = request.COOKIES.get( 'username111' ) return render(request, 'index.html' , { 'current_user' : v}) |
utils-->pagination.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | from django.utils.safestring import mark_safe class Page: def __init__( self ,current_page,data_count,per_page_count = 10 ,pager_num = 7 ): self .current_page = current_page self .data_count = data_count self .per_page_count = per_page_count self .pager_num = pager_num @property def start( self ): return ( self .current_page - 1 ) * self .per_page_count @property def end( self ): return self .current_page * self .per_page_count @property def total_count( self ): v, y = divmod ( self .data_count, self .per_page_count) if y: v = v + 1 return v def page_str( self ,base_url): page_list = [] if self .total_count < self .pager_num: start_index = 1 end_index = self .total_count + 1 else : if self .current_page < = ( self .pager_num + 1 ) / 2 : start_index = 1 end_index = self .pager_num + 1 else : start_index = self .current_page - ( self .pager_num - 1 ) / 2 end_index = self .current_page + ( self .pager_num + 1 ) / 2 if ( self .current_page + ( self .pager_num - 1 ) / 2 ) > self .total_count: end_index = self .total_count + 1 start_index = self .total_count - self .pager_num + 1 if self .current_page = = 1 : prev = '<a class="page" href="javascript:void(0)">上一页</a>' else : prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self .current_page - 1 ) page_list.append(prev) for i in range ( int (start_index), int (end_index)): if i = = self .current_page: temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url,i, i) else : temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url,i, i) page_list.append(temp) if self .current_page = = self .total_count: nex = '<a class="page" href="javascript:void(0);">下一页</a>' else : nex = '<a class="page" href=%s?p=%s>下一页</a>' % (base_url, self .current_page + 1 ) page_list.append(nex) jump = ''' <input type='text'/><a onclick='jumpTo(this,"%s?p=");'>Go</a> <script> function jumpTo(ths,base){ var val=ths.previousSibling.value; location.href=base+val; } </script> ''' % (base_url) page_list.append(jump) page_str = mark_safe("".join(page_list)) return page_str |
login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <form action = "/login/" method = "POST" > < input type = "text" name = "username" placeholder = "用户名" / > < input type = "password" name = "pwd" placeholder = "密码" / > < input type = "submit" / > < / form> < / body> < / html> |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <h1>欢迎登录:{{current_user}}< / h1> < / body> < / html> |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
· 用 C# 插值字符串处理器写一个 sscanf