Next, in the previous article, JavaScript files are merged and compressed to remove duplicate references. cache loading is delayed.
[Csharp]
Public static void AppendJsFile (this HtmlHelper htmlHelper, string jsFile, int group = 1)
Public static MvcHtmlString RenderJsFile (this HtmlHelper htmlHelper)
It is only used in MVC. The answer is yes.
Let's talk about the idea first. In fact, it's easy to take over the output stream. How can we take over the output stream? Add the following code to the Global. asax file:
[Csharp]
Public override void Init ()
{
Base. Init ();
This. ReleaseRequestState + = new EventHandler (InstallResponseFilter );
}
Private void InstallResponseFilter (object sender, EventArgs e)
{
HttpResponse response = HttpContext. Current. Response;
If (response. ContentType = "text/html ")
Response. Filter = new PageFilter (response. Filter );
}
I still use the previous project for demo.
There is no difference with our usual development, but the returned results are as follows:
We can see that both the js file and js text are merged and compressed.
The key is the credit of PageFilter.
The Code is as follows:
[Html]
Public class PageFilter: Stream
{
Stream responseStream;
Long position;
StringBuilder responseHtml;
Public PageFilter (Stream inputStream)
{
ResponseStream = inputStream;
ResponseHtml = new StringBuilder ();
}
# Region Filter overrides
Public override bool CanRead
{
Get {return true ;}
}
Public override bool CanSeek
{
Get {return true ;}
}
Public override bool CanWrite
{
Get {return true ;}
}
Public override void Close ()
{
ResponseStream. Close ();
}
Public override void Flush ()
{
ResponseStream. Flush ();
}
Public override long Length
{
Get {return 0 ;}
}
Public override long Position
{
Get {return position ;}
Set {position = value ;}
}
Public override long Seek (long offset, SeekOrigin origin)
{
Return responseStream. Seek (offset, origin );
}
Public override void SetLength (long length)
{
ResponseStream. SetLength (length );
}
Public override int Read (byte [] buffer, int offset, int count)
{
Return responseStream. Read (buffer, offset, count );
}
# Endregion
# Region Dirty work
Public override void Write (byte [] buffer, int offset, int count)
{
HttpResponse response = HttpContext. Current. Response;
String charset = response. Charset ?? "UTF-8 ";
String strBuffer = Encoding. GetEncoding (charset). GetString (buffer, offset, count );
Int bodyindex = strBuffer. ToLower (). LastIndexOf ("</body> ");
// Js text
Regex reg = new Regex ("<script [^>] *> (? <Content> [^ <] *) </script> ", RegexOptions. IgnoreCase | RegexOptions. Multiline );
// Js reference
Regex regSrc = new Regex ("src = \"? (? <Src> [^ '\ ">] *) \"? ", RegexOptions. IgnoreCase | RegexOptions. Multiline );
StringBuilder jsContent = new StringBuilder ();
List <string> jsSrc = new List <string> ();
MatchCollection mc = reg. Matches (strBuffer );
If (mc. Count> 0)
{
# Region find the js part
Foreach (Match m in mc)
{
String str = m. Groups ["content"]. Value;
If (! String. IsNullOrEmpty (str ))
{
JsContent. AppendLine (str); // find the js text
}
Else
{
// Find the js reference
Match mSrc = regSrc. Match (m. Value );
If (mSrc! = Null & mSrc. Success)
{
String temp = mSrc. Groups ["src"]. Value;
If (! JsSrc. Contains (temp ))
JsSrc. Add (temp );
}
}
}
# Endregion
StrBuffer = reg. Replace (strBuffer, string. Empty );
If (bodyindex <0)
{
// The html document is not finished yet
MergerJs (jsContent, jsSrc );
}
Else
{
# Region html with end tag
MergerJs (jsContent, jsSrc );
// Generate a new js reference
String jsFileFormat = "<script type = \" text/javascript \ "src = \" {0} \ "> </script> ";
String jshref = string. Format (jsFileFormat, "http: // localhost: 58798/js. ashx? Href = "+ string. Join (", ", jsSrc ));
// Generate new js text
String jstextFormat = "<script type = \" text/javascript \ "> {0} </script> ";
// Compress js text
String jsContentstr = JavaScriptCompressor. Compress (jsContent. ToString ());
String jsText = string. Format (jstextFormat, jsContentstr );
// Insert the newly generated js
Bodyindex = strBuffer. ToLower (). LastIndexOf ("</body> ");
StrBuffer = strBuffer. Insert (bodyindex, jshref + Environment. NewLine + jsText );
# Endregion
}
Byte [] data = Encoding. GetEncoding (charset). GetBytes (strBuffer );
ResponseStream. Write (data, 0, data. Length );
}
Else {
ResponseStream. Write (buffer, offset, count );
}
}
Void MergerJs (StringBuilder jsContent, List <string> jsSrc)
{
String jsTextKey = "jsTextKey ";
String jsFileKey = "jsFileKey ";
If (! HttpContext. Current. Items. Contains (jsTextKey ))
HttpContext. Current. Items. Add (jsTextKey, jsContent );
Else
{
StringBuilder jsTexttemp = HttpContext. Current. Items [jsTextKey] as StringBuilder;
JsContent. Insert (0, jsTexttemp. ToString ());
}
If (! HttpContext. Current. Items. Contains (jsFileKey ))
HttpContext. Current. Items. Add (jsFileKey, jsSrc );
Else
{
List <string> jsfiletemp = HttpContext. Current. Items [jsTextKey] as List <string>;
JsSrc. InsertRange (0, jsfiletemp );
}
}
# Endregion
}
After talking about this, We only provide an idea, a js merge idea, and pay attention to the details in real projects.
From the column dz45693