轉自/archive////jsonviewerextjsmvcfiddl
項目的表現層使用MVC+Extjs在開發過程中一旦頁面顯示不正常第一個需要排查的總是Action是否輸出了正確的Json?由於開發人員會日復一日地頻繁進行這個操作所以我們的目標是要找到一種方法可以
不用耗費額外的精力隨時查看Json輸出
不用耗費額外的精力指的是當需要查看Json輸出時只要轉轉眼球(可能至少還需要點兩下鼠標恐怕)就能很快找到想看的結果
查看Json輸出的方法很多我們所能找的最接近這個目標的方案是Fiddler+JsonViewer插件+自定義Fiddler過濾條件想要查看Json輸出時只要先將Fiddler運行起來然後在浏覽器裡正常操作Web頁面就可以在Fiddler裡面看到截獲的Json輸出了效果如下圖所示
安裝Fiddler+JsonViewer插件
Fiddler是一款老牌Web調試工具下載安裝之後通過點擊開始|程序|Fiddler或點擊IE的菜單工具|Fiddler將其運行起來後它會自動把自己注冊成IE的代理服務器從而截獲任何經過IE的請求/應答當關閉它時它又會自動把代理服務器配置取消(當年使用Fiddler的時候還得自己添加代理服務器配置很麻煩的說)
JsonViewer是一款查看Json對象的小工具解壓後可以看到個子目錄
JsonView可獨立運行版
VisualizerVS插件
FiddlerFiddler插件
我們接下來要安裝JsonViewer的Fiddler插件方法是將Fiddler目錄中的所有文件復制到Fiddler的安裝目錄\Inspectors\然後修改Fiddler的安裝目錄\nfig如下圖所示粗體部分是需要我們添加的配置信息
nfig
<configuration>
<runtime>
<generatePublisherEvidence enabled=false/>
<assemblyBinding xmlns=urn:schemasmicrosoftcom:asmv>
<probing privatePath=Inspectors />
</assemblyBinding>
</runtime>
</configuration>
注意 IE 和 NET Framework 被硬編碼成只要是對localhost的請求就不通過代理服務器所以像x這樣的請求不會被Fiddler截獲解決方法是) 將localhost替換成localhost如x) 將localhost替換成本機IP地址如x
現在讓我們把Fiddler運行起來再操作一下頁面就可以在Fiddler窗體左側的Web Sessions列表裡看到一大堆請求/應答點擊返回Json的那一條再點擊進入右側的InspectorsJsonTab頁就可以了只是Fiddler默認會把所有經過IE的任何請求/應答全都顯示出來這樣一來Web Sessions列表裡的東東就嫌太多了能不能把與Json不相干的東東全部過濾掉呢?這個並不難只要在Fiddler的CustomRules裡面增加幾行代碼就可以了
自定義過濾條件
點擊Fiddler的菜單Rules|Customize Rules會自動由記事本打開可添加自定義規則的代碼文件
在第行增加如下代碼目的是在Fiddler的Rules菜單裡增加一個只顯示Json的菜單項
// jcl
public static RulesOption(只顯示 &Json)
var m_ShowJsonOnly: boolean = false;
在OnBeforeResponse事件裡增加如下代碼意思是如果Rules|只顯示Json菜單項被選中了就過濾掉所有ContentType!=application/json; charset=utf的應答
// jcl:
if(m_ShowJsonOnly) {
//MessageBoxShow(oSessionoResponseheadersItem(ContentType)ToString());
if (!oSessionoResponseheadersExistsAndContains(ContentType application/json; charset=utf)) {
oSession[uihide] = hide; // String value not important
}
}
所有源碼在此
自定義規則
import System;
import SystemWindowsForms;
import Fiddler;
// GLOBALIZATION NOTE:
// Be sure to save this file with UTF Encoding if using any nonASCII characters
// in strings etc
//
// JScript Reference
//
//
// FiddlerScript Reference
//
//
// FiddlerScript Editor:
//
class Handlers
{
// The following snippet demonstrates a custombound column for the web sessions list
// See for more info
//public static BindUIColumn(Method )
//function FillMethodColumn(oS: Session){
// if ((oSoRequest != null) && (oSoRequestheaders != null))
// return oSoRequestheadersHTTPMethod; else return StringEmpty;
//}
public static RulesOption(Hide s)
var m_Hides: boolean = false;
// Cause Fiddler to override the AcceptLanguage header with one of the defined values
public static RulesOption(Request &Japanese Content)
var m_Japanese: boolean = false;
// Cause Fiddler to override the UserAgent header with one of the defined values
RulesString(&UserAgents true)
RulesStringValue(Netscape & Mozilla/ (Win; I))
RulesStringValue(&IEMobile Mozilla/ (compatible; MSIE ; Windows CE; IEMobile ))
RulesStringValue(&Safari (XP) Mozilla/ (Windows; U; Windows NT ; enUS) AppleWebKit/ (KHTML like Gecko) Version/ Safari/)
RulesStringValue(IE & (XPSP) Mozilla/ (compatible; MSIE ; Windows NT ; SV))
RulesStringValue(IE & (Vista) Mozilla/ (compatible; MSIE ; Windows NT ; SLCC))
RulesStringValue(IE & (Wink x) Mozilla/ (compatible; MSIE ; Windows NT ; WOW; Trident/))
RulesStringValue(IE (Win) Mozilla/ (compatible; MSIE ; Windows NT ; Trident/))
RulesStringValue(IE (IE CompatMode) Mozilla/ (compatible; MSIE ; Windows NT ; Trident/))
RulesStringValue(&Opera Opera/ (Windows NT ; U; en) Presto/ Version/)
RulesStringValue(&Firefox Mozilla/ (Windows; U; Windows NT ; enUS; rv:) Gecko/ Firefox/)
RulesStringValue(&Firefox Mozilla/ (Windows; U; Windows NT ; enUS; rv:) Gecko/ Firefox/)
RulesStringValue(&Firefox (Mac) Mozilla/ (Macintosh; U; Intel Mac OS X ; enUS; rv:) Gecko/ Firefox/)
RulesStringValue(Chrome Mozilla/ (Windows; U; Windows NT ; enUS) AppleWebKit/ (KHTML like Gecko) Chrome/ Safari/)
RulesStringValue(&Custom %CUSTOM%)
public static var sUA: String = null;
// Cause Fiddler to delay HTTP traffic to simulate typical k modem conditions
public static RulesOption(Simulate &Modem speeds Per&formance)
var m_SimulateModem: boolean = false;
// Removes HTTPcaching related headers and specifies nocache on requests and responses
public static RulesOption(&Disable Caching Per&formance)
var m_DisableCaching: boolean = false;
// Show the duration between the start of RequestSend and ResponseCompleted in Milliseconds
public static RulesOption(&Show TimetoLastByte Per&formance)
var m_ShowTTLB: boolean = false;
// Show the time of response completion
public static RulesOption(Show Response &Timestamp Per&formance)
var m_ShowTimestamp: boolean = false;
// Create a new option on the Rules menu Set the default value for the option
public static RulesOption(&UNTITLED)
var m_bUNTITLED: boolean = false;
// Create a new item on the Tools menu
public static ToolsAction(&UNTITLED)
function DoUNTITLED(oSessions: FiddlerSession[]){
// Write your code here
}
// jcl
public static RulesOption(只顯示 &Json)
var m_ShowJsonOnly: boolean = false;
// Force a manual reload of the script file Resets all
// RulesOption variables to their defaults
public static ToolsAction(Reset Script)
function DoManualReload(){
FiddlerObjectReloadScript();
}
public static ContextAction(Decode Selected Sessions)
function DoRemoveEncoding(oSessions: Session[]){
for (var x = ; x < oSessionsLength; x++){
oSessions[x]utilDecodeRequest();
oSessions[x]utilDecodeResponse();
}
}
static function OnBoot(){
// MessageBoxShow(Fiddler has finished booting);
// SystemDiagnosticsProcessStart(iexploreexe);
// FiddlerObjectUIActivateRequestInspector(HEADERS);
// FiddlerObjectUIActivateResponseInspector(HEADERS);
}
static function OnShutdown(){
// MessageBoxShow(Fiddler has shutdown);
}
static function OnAttach(){
// MessageBoxShow(Fiddler is now the system proxy);
// SystemDiagnosticsProcessStart(proxycfgexe u); // Notify WinHTTP of proxy change
}
static function OnDetach(){
// MessageBoxShow(Fiddler is no longer the system proxy);
// SystemDiagnosticsProcessStart(proxycfgexe u); // Notify WinHTTP of proxy change
}
static function OnBeforeRequest(oSession: Session)
{
// Sample Rule: Color ASPX requests in RED
// if (oSessionuriContains(aspx)) { oSession[uicolor] = red; }
// Sample Rule: Flag POSTs to in italics
// if (oSessionHostnameIs() && oSessionHTTPMethodIs(POST)) { oSession[uiitalic] = yup; }
// Sample Rule: Break requests for URLs containing /sandbox/
// if (oSessionuriContains(/sandbox/)){
// oSessionoFlags[xbreakrequest] = yup; // Existence of the xbreakrequest flag creates a breakpoint; the yup value is unimportant
// }
if ((null != gs_ReplaceToken) && (oSessionurlindexOf(gs_ReplaceToken)>)){ // Case sensitive
oSessionurl = oSessionurlReplace(gs_ReplaceToken gs_ReplaceTokenWith);
}
if ((null != gs_OverridenHost) && (oSessionhosttoLowerCase() == gs_OverridenHost)){
oSession[xoverridehost] = gs_OverrideHostWith;
}
if ((null!=bpRequestURI) && oSessionuriContains(bpRequestURI)){
oSession[xbreakrequest]=uri;
}
if ((null!=bpMethod) && (oSessionHTTPMethodIs(bpMethod))){
oSession[xbreakrequest]=method;
}
if ((null!=uiBoldURI) && oSessionuriContains(uiBoldURI)){
oSession[uibold]=QuickExec;
}
if (m_SimulateModem){
// Delay sends by ms per KB uploaded
oSession[requesttrickledelay] = ;
}
if (m_DisableCaching){
oSessionoRequestheadersRemove(IfNoneMatch);
oSessionoRequestheadersRemove(IfModifiedSince);
oSessionoRequest[Pragma] = nocache;
}
// UserAgent Overrides
if (null != sUA){
oSessionoRequest[UserAgent] = sUA;
}
if (m_Japanese){
oSessionoRequest[AcceptLanguage] = ja;
}
}
static function OnBeforeResponse(oSession: Session)
{
if (m_SimulateModem){
// Delay receives by ms per KB downloaded
oSession[responsetrickledelay] = ;
}
if (m_DisableCaching){
oSessionoResponseheadersRemove(Expires);
oSessionoResponse[CacheControl] = nocache;
}
if (m_ShowTimestamp){
oSession[uicustomcolumn] = DateTimeNowToString(H:mm:ssffff) + + oSession[uicustomcolumn];
}
if (m_ShowTTLB){
oSession[uicustomcolumn] = oSessionoResponseiTTLB + ms + oSession[uicustomcolumn];
}
if (m_Hides && oSessionresponseCode == ){
oSession[uihide] = true;
}
if ((bpStatus>) && (oSessionresponseCode == bpStatus)){
oSession[xbreakresponse]=status;
}
if ((null!=bpResponseURI) && oSessionuriContains(bpResponseURI)){
oSession[xbreakresponse]=uri;
}
// jcl:
if(m_ShowJsonOnly) {
//MessageBoxShow(oSessionoResponseheadersItem(ContentType)ToString());
if (!oSessionoResponseheadersExistsAndContains(ContentType application/json; charset=utf)) {
oSession[uihide] = hide; // String value not important
}
}
// Uncomment to reduce incidence of unexpected socket closure exceptions in NET code
// Note that you really should also fix your NET code to gracefully handle unexpected connection closure
//
// if (!(((oSessionresponseCode == ) && oSessionoResponse[WWWAuthenticate]Length > ) ||
// ((oSessionresponseCode == ) && oSessionoResponse[ProxyAuthenticate]Length > ))) {
// oSessionoResponse[Connection] = close;
// }
}
static function Main()
{
var today: Date = new Date();
FiddlerObjectStatusText = CustomRulesjs was loaded at: + today;
// Uncomment to add a Server column containing the response Server header if present
// FiddlerObjectUIlvSessionsAddBoundColumn(Server @responseserver);
}
// These static variables are used for simple breakpointing & other QuickExec rules
static var bpRequestURI:String = null;
static var bpResponseURI:String = null;
static var bpStatus:int = ;
static var bpMethod: String = null;
static var uiBoldURI: String = null;
static var gs_ReplaceToken: String = null;
static var gs_ReplaceTokenWith: String = null;
static var gs_OverridenHost: String = null;
static var gs_OverrideHostWith: String = null;
// The OnExecAction function is called by either the QuickExec box in the Fiddler window
// or by the ExecActionexe command line utility
static function OnExecAction(sParams: String[]){
FiddlerObjectStatusText = ExecAction: + sParams[];
var sAction = sParams[]toLowerCase();
switch (sAction){
case bold:
if (sParamsLength<) {uiBoldURI=null; FiddlerObjectStatusText=Bolding cleared; return;}
uiBoldURI = sParams[]; FiddlerObjectStatusText=Bolding requests for + uiBoldURI;
break;
case bp:
FiddlerObjectalert(bpu = breakpoint request for uri\nbpm = breakpoint request method\nbps=breakpoint response status\nbpafter = breakpoint response for URI);
break;
case bps:
if (sParamsLength<) {bpStatus=; FiddlerObjectStatusText=Response Status breakpoint cleared; return;}
bpStatus = parseInt(sParams[]); FiddlerObjectStatusText=Response status breakpoint for + sParams[];
break;
case bpv:
case bpm:
if (sParamsLength<) {bpMethod=null; FiddlerObjectStatusText=Request Method breakpoint cleared; return;}
bpMethod = sParams[]toUpperCase(); FiddlerObjectStatusText=Request Method breakpoint for + bpMethod;
break;
case bpu:
if (sParamsLength<) {bpRequestURI=null; FiddlerObjectStatusText=RequestURI breakpoint cleared; return;}
if (sParams[]toLowerCase()StartsWith(//)){sParams[] = sParams[]Substring();}
bpRequestURI = sParams[];
FiddlerObjectStatusText=RequestURI breakpoint for +sParams[];
break;
case bpafter:
if (sParamsLength<) {bpResponseURI=null; FiddlerObjectStatusText=ResponseURI breakpoint cleared; return;}
if (sParams[]toLowerCase()StartsWith(//)){sParams[] = sParams[]Substring();}
bpResponseURI = sParams[];
FiddlerObjectStatusText=ResponseURI breakpoint for +sParams[];
break;
case overridehost:
if (sParamsLength<) {gs_OverridenHost=null; FiddlerObjectStatusText=Host Override cleared; return;}
gs_OverridenHost = sParams[]toLowerCase();
gs_OverrideHostWith = sParams[];
FiddlerObjectStatusText=Connecting to [ + gs_OverrideHostWith + ] for requests to [ + gs_OverridenHost + ];
break;
case urlreplace:
if (sParamsLength<) {gs_ReplaceToken=null; FiddlerObjectStatusText=URL Replacement cleared; return;}
gs_ReplaceToken = sParams[];
gs_ReplaceTokenWith = sParams[]Replace( %); // Simple helper
FiddlerObjectStatusText=Replacing [ + gs_ReplaceToken + ] in URIs with [ + gs_ReplaceTokenWith + ];
break;
case select:
if (sParamsLength<) { FiddlerObjectStatusText=Please specify ContentType to select; return;}
FiddlerObjectUIactSelectSessionsWithResponseHeaderValue(ContentType sParams[]);
MessageBoxShow(sParams[]);
FiddlerObjectStatusText=Selected sessions returning ContentType: + sParams[] + ;
if (FiddlerObjectUIlvSessionsSelectedItemsCount > ){
FiddlerObjectUIlvSessionsFocus();
}
break;
case allbut:
case keeponly:
if (sParamsLength<) { FiddlerObjectStatusText=Please specify ContentType to retain during wipe; return;}
FiddlerObjectUIactSelectSessionsWithResponseHeaderValue(ContentType sParams[]);
MessageBoxShow(sParams[]);
FiddlerObjectUIactRemoveUnselectedSessions();
FiddlerObjectUIlvSessionsSelectedItemsClear();
FiddlerObjectStatusText=Removed all but ContentType: + sParams[];
break;
case stop:
FiddlerObjectUIactDetachProxy();
break;
case start:
FiddlerObjectUIactAttachProxy();
break;
case cls:
case clear:
FiddlerObjectUIactRemoveAllSessions();
break;
case g:
case go:
FiddlerObjectUIactResumeAllSessions();
break;
case help:
UtilitiesLaunchHyperlink();
break;
case hide:
FiddlerObjectUIactMinimizeToTray();
break;
case nuke:
FiddlerObjectUIactClearWinINETCache();
FiddlerObjectUIactClearWinINETCookies();
break;
case show:
FiddlerObjectUIactRestoreWindow();
break;
case tail:
if (sParamsLength<) { FiddlerObjectStatusText=Please specify # of sessions to trim the session list to; return;}
FiddlerObjectUITrimSessionList(intParse(sParams[]));
break;
case quit:
FiddlerObjectUIactExit();
break;
case dump:
FiddlerObjectUIactSelectAll();
FiddlerObjectUIactSaveSessionsToZip(CONFIGGetPath(Captures) + dumpsaz);
FiddlerObjectUIactRemoveAllSessions();
FiddlerObjectStatusText = Dumped all sessions to + CONFIGGetPath(Captures) + dumpsaz;
break;
default:
if (sActionStartsWith(http) || sActionStartsWith(www)){
SystemDiagnosticsProcessStart(sAction);
}
else
FiddlerObjectStatusText = Requested ExecAction: + sAction + not found Type HELP to learn more;
}
}
}
現在Web Sessions列表已經清爽多了可是如果我們想忙裡偷閒去博客園首頁逛逛就會發現Web Sessions列表裡面多了幾條博客園首頁的Json輸出這是因為Fiddler默認會截獲所有經由IE的請求/應答能不能讓它只顯示本機的請求/應答呢?這個只需要配置一下Fiddler的Filter選項就可以了如下圖所示
From:http://tw.wingwit.com/Article/program/net/201311/12309.html