16-djongo中間件學習

前戲

我們在前面的課程中已經學會了給視圖函數加裝飾器來判斷是用戶是否登錄,把沒有登錄的用戶請求跳轉到登錄頁面。我們通過給幾個特定視圖函數加裝飾器實現了這個需求。但是以后添加的視圖函數可能也需要加上裝飾器,這樣是不是稍微有點繁瑣。

學完今天的內容之后呢,我們就可以用更適宜的方式來實現類似給所有請求都做相同操作的功能了。

中間件

中間件介紹

什么是中間件?

官方的說法:中間件是一個用來處理Django的請求和響應的框架級別的鉤子。它是一個輕量、低級別的插件系統,用于在全局范圍內改變Django的輸入和輸出。每個中間件組件都負責做一些特定的功能。

但是由于其影響的是全局,所以需要謹慎使用,使用不當會影響性能。

說的直白一點中間件是幫助我們在視圖函數執行之前和執行之后都可以做一些額外的操作,它本質上就是一個自定義類,類中定義了幾個方法,Django框架會在處理請求的特定的時間去執行這些方法。

我們一直都在使用中間件,只是沒有注意到而已,打開Django項目的Settings.py文件,看到下圖的MIDDLEWARE配置項。

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

MIDDLEWARE配置項是一個列表,列表中是一個個字符串,這些字符串其實是一個個類,也就是一個個中間件。

我們之前已經接觸過一個csrf相關的中間件了?我們一開始讓大家把他注釋掉,再提交post請求的時候,就不會被forbidden了,后來學會使用csrf_token之后就不再注釋這個中間件了。

那接下來就學習中間件中的方法以及這些方法什么時候被執行。

自定義中間件

中間件可以定義五個方法,分別是:(主要的是process_request和process_response)

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

以上方法的返回值可以是None或一個HttpResponse對象,如果是None,則繼續按照django定義的規則向后繼續執行,如果是HttpResponse對象,則直接將該對象返回給用戶。

自定義一個中間件示例

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return response

process_request

process_request有一個參數,就是request,這個request和視圖函數中的request是一樣的。

它的返回值可以是None也可以是HttpResponse對象。返回值是None的話,按正常流程繼續走,交給下一個中間件處理,如果是HttpResponse對象,Django將不執行視圖函數,而將響應對象返回給瀏覽器。

我們來看看多個中間件時,Django是如何執行其中的process_request方法的。

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")

在settings.py的MIDDLEWARE配置項中注冊上述兩個自定義中間件:

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','middlewares.MD1',  # 自定義中間件MD1'middlewares.MD2'  # 自定義中間件MD2
]

此時,我們訪問一個視圖,會發現終端中打印如下內容:

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index視圖

把MD1和MD2的位置調換一下,再訪問一個視圖,會發現終端中打印的內容如下:

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index視圖

看結果我們知道:視圖函數還是最后執行的,MD2比MD1先執行自己的process_request方法。

在打印一下兩個自定義中間件中process_request方法中的request參數,會發現它們是同一個對象。

由此總結一下:

  1. 中間件的process_request方法是在執行視圖函數之前執行的。
  2. 當配置多個中間件時,會按照MIDDLEWARE中的注冊順序,也就是列表的索引值,從前到后依次執行的。
  3. 不同中間件之間傳遞的request都是同一個對象

?

process_response

它有兩個參數,一個是request,一個是response,request就是上述例子中一樣的對象,response是視圖函數返回的HttpResponse對象。該方法的返回值也必須是HttpResponse對象。

給上述的M1和M2加上process_response方法:

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responseclass MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return response

訪問一個視圖,看一下終端的輸出:

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index視圖
MD1里面的 process_response
MD2里面的 process_response

看結果可知:

process_response方法是在視圖函數之后執行的,并且順序是MD1比MD2先執行。(此時settings.py中 MD2比MD1先注冊)

多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執行的,也就是說第一個中間件的process_request方法首先執行,而它的process_response方法最后執行,最后一個中間件的process_request方法最后一個執行,它的process_response方法是最先執行。

?

process_view

process_view(self, request, view_func, view_args, view_kwargs)

該方法有四個參數

request是HttpRequest對象。

view_func是Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱作為字符串。)

view_args是將傳遞給視圖的位置參數的列表.

view_kwargs是將傳遞給視圖的關鍵字參數的字典。 view_args和view_kwargs都不包含第一個視圖參數(request)。

Django會在調用視圖函數之前調用process_view方法。

它應該返回None或一個HttpResponse對象。 如果返回None,Django將繼續處理這個請求,執行任何其他中間件的process_view方法,然后在執行相應的視圖。 如果它返回一個HttpResponse對象,Django不會調用適當的視圖函數。 它將執行中間件的process_response方法并將應用到該HttpResponse并返回結果。

?給MD1和MD2添加process_view方法:

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD1 中的process_view")print(view_func, view_func.__name__)class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD2 中的process_view")print(view_func, view_func.__name__)

訪問index視圖函數,看一下輸出結果:

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001DE68317488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001DE68317488> index
app01 中的 index視圖
MD1里面的 process_response
MD2里面的 process_response

process_view方法是在process_request之后,視圖函數之前執行的,執行順序按照MIDDLEWARE中的注冊順序從前到后順序執行的

process_exception

process_exception(self, request, exception)

該方法兩個參數:

一個HttpRequest對象

一個exception是視圖函數異常產生的Exception對象。

這個方法只有在視圖函數中出現異常了才執行,它返回的值可以是一個None也可以是一個HttpResponse對象。如果是HttpResponse對象,Django將調用模板和中間件中的process_response方法,并返回給瀏覽器,否則將默認處理異常。如果返回一個None,則交給下一個中間件的process_exception方法來處理異常。它的執行順序也是按照中間件注冊順序的倒序執行。

?給MD1和MD2添加上這個方法:

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD1 中的process_view")print(view_func, view_func.__name__)def process_exception(self, request, exception):print(exception)print("MD1 中的process_exception")class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD2 中的process_view")print(view_func, view_func.__name__)def process_exception(self, request, exception):print(exception)print("MD2 中的process_exception")

如果視圖函數中無異常,process_exception方法不執行。

想辦法,在視圖函數中拋出一個異常:

def index(request):print("app01 中的 index視圖")raise ValueError("呵呵")return HttpResponse("O98K")

在MD1的process_exception中返回一個響應對象:

class MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD1 中的process_view")print(view_func, view_func.__name__)def process_exception(self, request, exception):print(exception)print("MD1 中的process_exception")return HttpResponse(str(exception))  # 返回一個響應對象

看輸出結果:

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x0000022C09727488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x0000022C09727488> index
app01 中的 index視圖
呵呵
MD1 中的process_exception
MD1里面的 process_response
MD2里面的 process_response

注意,這里并沒有執行MD2的process_exception方法,因為MD1中的process_exception方法直接返回了一個響應對象。

process_template_response(用的比較少)

process_template_response(self, request, response)

它的參數,一個HttpRequest對象,response是TemplateResponse對象(由視圖函數或者中間件產生)。

process_template_response是在視圖函數執行完成后立即執行,但是它有一個前提條件,那就是視圖函數返回的對象有一個render()方法(或者表明該對象是一個TemplateResponse對象或等價方法)。

class MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD1 中的process_view")print(view_func, view_func.__name__)def process_exception(self, request, exception):print(exception)print("MD1 中的process_exception")return HttpResponse(str(exception))def process_template_response(self, request, response):print("MD1 中的process_template_response")return responseclass MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD2 中的process_view")print(view_func, view_func.__name__)def process_exception(self, request, exception):print(exception)print("MD2 中的process_exception")def process_template_response(self, request, response):print("MD2 中的process_template_response")return response

views.py中:

def index(request):print("app01 中的 index視圖")def render():print("in index/render")return HttpResponse("O98K")rep = HttpResponse("OK")rep.render = renderreturn rep

訪問index視圖,終端輸出的結果:

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001C111B97488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001C111B97488> index
app01 中的 index視圖
MD1 中的process_template_response
MD2 中的process_template_response
in index/render
MD1里面的 process_response
MD2里面的 process_response

從結果看出:

視圖函數執行完之后,立即執行了中間件的process_template_response方法,順序是倒序,先執行MD1的,在執行MD2的,接著執行了視圖函數返回的HttpResponse對象的render方法,返回了一個新的HttpResponse對象,接著執行中間件的process_response方法。

中間件的執行流程

上一部分,我們了解了中間件中的5個方法,它們的參數、返回值以及什么時候執行,現在總結一下中間件的執行流程。

請求到達中間件之后,先按照正序執行每個注冊中間件的process_reques方法,process_request方法返回的值是None,就依次執行,如果返回的值是HttpResponse對象,不再執行后面的process_request方法,而是執行當前對應中間件的process_response方法,將HttpResponse對象返回給瀏覽器。也就是說:如果MIDDLEWARE中注冊了6個中間件,執行過程中,第3個中間件返回了一個HttpResponse對象,那么第4,5,6中間件的process_request和process_response方法都不執行,順序執行3,2,1中間件的process_response方法。

?

process_request方法都執行完后,匹配路由,找到要執行的視圖函數,先不執行視圖函數,先執行中間件中的process_view方法,process_view方法返回None,繼續按順序執行,所有process_view方法執行完后執行視圖函數。假如中間件3 的process_view方法返回了HttpResponse對象,則4,5,6的process_view以及視圖函數都不執行,直接從最后一個中間件,也就是中間件6的process_response方法開始倒序執行。

process_template_response和process_exception兩個方法的觸發是有條件的,執行順序也是倒序。總結所有的執行流程如下:

?

中間件版登錄驗證?

中間件版的登錄驗證需要依靠session,所以數據庫中要有django_session表。

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^login/$', views.login, name='login'),url(r'^index/$', views.index, name='index'),url(r'^home/$', views.home, name='home'),
]urls.py
View Code

views.py

from django.shortcuts import render, HttpResponse, redirectdef index(request):return HttpResponse('this is index')def home(request):return HttpResponse('this is home')def login(request):if request.method == "POST":user = request.POST.get("user")pwd = request.POST.get("pwd")if user == "alex" and pwd == "alex3714":# 設置sessionrequest.session["user"] = user# 獲取跳到登陸頁面之前的URLnext_url = request.GET.get("next")# 如果有,就跳轉回登陸之前的URLif next_url:return redirect(next_url)# 否則默認跳轉到index頁面else:return redirect("/index/")return render(request, "login.html")
views.py

login.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>登錄頁面</title>
</head>
<body>
<form action="{% url 'login' %}" method="post">{% csrf_token %}<p><label for="user">用戶名:</label><input type="text" name="user" id="user"></p><p><label for="pwd">密 碼:</label><input type="text" name="pwd" id="pwd"></p><input type="submit" value="登錄">
</form>
</body>
</html>
login.html

middlewares.py

from django.utils.deprecation import MiddlewareMixinclass AuthMD(MiddlewareMixin):white_list = ['/login/', ]  # 白名單black_list = ['/black/', ]  # 黑名單def process_request(self, request):from django.shortcuts import redirect, HttpResponsenext_url = request.path_infoprint(request.path_info, request.get_full_path())# 黑名單的網址限制訪問if next_url in self.black_list:return HttpResponse('This is an illegal URL')# 白名單的網址或者登陸用戶不做限制elif next_url in self.white_list or request.session.get("user"):returnelse:return redirect("/login/?next={}".format(next_url))中間件
middlewares.py

在settings.py中注冊

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','middlewares.AuthMD'
]
注冊中間件

AuthMD中間件注冊后,所有的請求都要走AuthMD的process_request方法。

如果URL在黑名單中,則返回This is an illegal URL的字符串;

訪問的URL在白名單內或者session中有user用戶名,則不做阻攔走正常流程;

正常的URL但是需要登錄后訪問,讓瀏覽器跳轉到登錄頁面。

注:AuthMD中間件中需要session,所以AuthMD注冊的位置要在session中間的下方。?

附:Django請求流程圖

轉載于:https://www.cnblogs.com/bai-max/p/9355282.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282669.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282669.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282669.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PHP基礎(必須熟練掌握的基礎)

<?php/*** 三元運算符的應用*/ /* $a 10; $b 15; echo $a > $b ? 1 : 0; */ // 注:php7新添加的運算符比較運算符x<>y // 如果x和y相等,就返回0,如果x>y,就返回1,如果x的值小于y,就返回-1/* $a "aaa"; $b "bbb"; echo $a.$b; *//*** …

子進程無法從標準輸入讀取數據

每個process對象最多只能調用一次start()方法&#xff0c;join([timeout])方法會阻塞調用process對象的進程&#xff0c;直到timeout時間超時&#xff0c;或者process進程退出。如果timeout設置為None&#xff0c;則無超時時間。對于linux操作系統的進程管理&#xff0c;父進程…

Eclipse控制項目的訪問名稱

Eclipse控制web項目的訪問名稱 web項目的訪問路徑&#xff08;名稱&#xff09;修改 1.點擊項目右鍵-》properties找到Context root 修改成我們需要的名字即可轉載于:https://www.cnblogs.com/pypua/articles/7379950.html

計算機一級選擇題已做完確認,計算機一級選擇題(附答案)

點擊藍字關注我們(1)按照需求功能的不同&#xff0c;信息系統已形成各種層次&#xff0c;計算機應用于管理是開始于:()A)信息處理B)人事管理C)決策支持D)事務處理正確答案&#xff1a;A解析&#xff1a;計算機用于管理&#xff0c;起源于計算機在辦公應用中對大量信息、數據的處…

參加51CTO培訓,PMP考試通過啦

為什么選擇考PMP&#xff1f;先介紹下自己的情況&#xff0c;畢業三年&#xff0c;單位類似于平臺&#xff0c;不做技術&#xff0c;常態的工作是文案、商務、市場都會涉及些&#xff0c;對未來也有些迷茫。受前輩點撥可以學一些通用的技能&#xff0c;于是我選擇了PMP&#xf…

如何查看服務器并發請求連接數

https://wenku.baidu.com/view/fb553d795acfa1c7aa00cc27?pcf2#1 轉載于:https://www.cnblogs.com/linewman/p/9918760.html

C# 二十年語法變遷之 C# 5 和 C# 6參考

C# 二十年語法變遷之 C# 5 和 C# 6參考https://benbowen.blog/post/two_decades_of_csharp_ii/自從 C# 于 2000 年推出以來&#xff0c;該語言的規模已經大大增加&#xff0c;我不確定任何人是否有可能在任何時候都對每一種語言特性都有深入的了解。因此&#xff0c;我想寫一系…

非涉密計算機檢查的通知,關于開展非涉密計算機及可移動存儲介質專項清理活動的緊急通知...

關于在全校范圍內開展非涉密計算機及可移動存儲介質專項清理活動的緊急通知密辦字[2009]01號各單位&#xff1a;為有效遏制木馬病毒和惡意代碼的蔓延趨勢&#xff0c;現在校內開展一次非涉密計算機及可移動存儲介質的專項清理活動&#xff0c;要求如下&#xff1a;1、所有涉密人…

Spring Cloud構建微服務架構:服務消費(基礎)

使用LoadBalancerClient在Spring Cloud Commons中提供了大量的與服務治理相關的抽象接口&#xff0c;包括DiscoveryClient、這里我們即將介紹的LoadBalancerClient等。對于這些接口的定義我們在上一篇介紹服務注冊與發現時已經說過&#xff0c;Spring Cloud做這一層抽象&#x…

oracle數據庫中VARCHAR2(50 CHAR) 和VARCHAR2(50) 有啥區別?

VARCHAR2&#xff08;50 char&#xff09;這種類型的字段最多放50個字符&#xff0c;不夠50個用空格填充&#xff1b;而VARCHAR2(50)最大允許存放50個字符&#xff0c;但是不足50個也不用空格填充。varchar2是變長字符串&#xff0c;與CHAR類型不同&#xff0c;它不會使用空格填…

《解密小米之互聯網下的商業奇跡》

解密小米《解密小米之互聯網下的商業奇跡》 磐石之心 清華大學出版社 2014/10/1 書籍&#xff1a;《非同凡響想,喬布斯啟示錄》 磐石之心&#xff1a;原名王斌&#xff0c;互聯網IT資深預言家&#xff0c;第一個提出互聯網未來競爭是在線生活方式的競爭&#xff1b;第一個提出3…

計算機內存的故障,計算機內存出現故障的解決方法

內存如果出現故障&#xff0c;會造成系統運行不穩定、程序異常出錯和*作系統無法安裝的故障&#xff0c;下面將列舉內存常見的故障排除實例。1)內存順序引起的計算機工作不正常故障現象&#xff1a;一臺p4計算機&#xff0c;使用的是華碩intel850芯片組的主板&#xff0c;兩條r…

2018暑假集訓---遞推遞歸----一只小蜜蜂hdu2044

一只小蜜蜂... Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 93249 Accepted Submission(s): 33187Problem Description 有一只經過訓練的蜜蜂只能爬向右側相鄰的蜂房&#xff0c;不能反向爬行。請編程計算蜜…

《ASP.NET Core 6框架揭秘》實例演示[28]:自定義一個服務器

作為ASP.NET Core請求處理管道的“龍頭”的服務器負責監聽和接收請求并最終完成對請求的響應。它將原始的請求上下文描述為相應的特性&#xff08;Feature&#xff09;&#xff0c;并以此將HttpContext上下文創建出來&#xff0c;中間件針對HttpContext上下文的所有操作將借助于…

高清攝像頭MIPI接口與ARM連接【轉】

本文轉載自&#xff1a;http://www.cnblogs.com/whw19818/p/5811299.html MIPI攝像頭常見于手機、平板中&#xff0c;支持500萬像素以上高清分辨率。它的全稱為“Mobile Industry Processor Interface”&#xff0c;分為MIPI DSI 和MIPI CSI&#xff0c;分別對應于視頻顯示和視…

算法(第4版)Robert Sedgewick 刷題 第一章(1)

/*** Description 顛倒數組排列順序* author SEELE* date 2017年8月17日 上午10:56:17* action sortArr*/public static void sortArr() {int[] b new int[6];int[] a { 1, 2, 3, 4, 5, 6, 7 };for (int i 0; i < a.length / 2; i) {int temp a[a.length - 1 - i];a[a.l…

9種排序算法在四種數據分布下的速度比較

9種算法分別是&#xff1a; 1.選擇排序 2.希爾排序 3.插入排序 4.歸并排序 5.快速排序 6.堆排序 7.冒泡排序 8.梳排序 9.雞尾酒排序 在不同的情形下&#xff0c;排序速度前三名也不盡相同 Random : 希爾>快排>歸并 Few unique : 快排>…

win7服務器端口被占用,高手親自幫您win7端口被占用的詳盡處理要領

今天有一位用戶說他安裝了win7系統以后&#xff0c;在使用中突然遇到了win7端口被占用的情況&#xff0c;估計還會有更多的網友以后也會遇到win7端口被占用的問題&#xff0c;所以今天我們先來分析分析&#xff0c;那我們要怎么面對這個win7端口被占用的問題呢&#xff1f;大家…

局部變量和參數傳遞的問題

<SCRIPT LANGUAGE"JavaScript">var bb 1;function aa(bb) { //這里傳遞參數相當于 var bb bb ;給形參bb賦值為1。&#xff08;又參數傳遞&#xff0c;相當于就是在函數中定義了一個局部變量并且給這個變量賦了初值1&#xff09;此bb非彼bb&#xff0c;是分別…

回車ajax顯示,ajax返回值中有回車換行、空格的解決方法分享

最近在寫一個頁面&#xff0c;用jquery ajax來實現判斷&#xff0c;剛寫好測試完全沒有問題&#xff0c;過了兩天發現出現問題&#xff0c;判斷不成了。后來發現所有alert出來的返回值前面都會加若干換行和空格。(至今不明白&#xff0c;同一臺電腦&#xff0c;同樣的環境&…