-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gzip compressed JavaScript file is corrupted #109
Comments
It is probably the Content-Type again as "application/x-javascript" won't be picked up by default. If so, this should get it working:
I'll add it to the default setting if that is it. |
Unfortunately this does not solve the problem. I also tried this:
But the translation is not working. |
Have you got other javascript with translations that do work? |
No, but I have a simple HTML file that is translated correctly. |
I'm suspicious of the fact that your context-type is "x-javascript" because I've not seen that before with ASP.NET: it's normally just "javascript". Any idea why that might be? There's no charset indicated in the response header. Are you sure it's UTF-8? |
@ content-type: @ encoding: Back to the problem: I found the cause but I don't understand why it was happening. The problem seemed to be IIS. The application was running on IIS, but it was not at all configured within the IIS manager. I don't even understand how it could run because it is not located in the default IIS directory. I created a new website within IIS and specified the application's root folder. I added a binding to a random local domain name like "local.test.project" and created a static DNS entry in my HOSTS file. Accessing the site with "local.test.project" without modifying anything else; the translation was working. The domain name used should not be relevant, should it? First I was accessing the web application like this:
And now it looks like this:
This should be totally irrelevant, right? So I guess it must have been some strange thing happening within IIS. All .aspx and .ascx files were correctly translated, but .html and .js files not. To sum it up: It now works correctly. Thank you once again for your help. |
Update: I changed the project's settings to use the Visual Studio Development Server as web server:
The translation is still working correctly. So it really must have been some weird IIS problem. |
I just want to emphasize one totally awesome thing that is working with this i18n module that I jused realized using the translation for JavaScript files. Translation is normally done like this in your markup:
If you need to have placeholders you can use any of these on the server side code:
or using the nugget parametrized syntax (which is a little harder to read)
But what do you do if you have placeholders on the client side (eg. JavaScript files)? You can do this:
First you would look at this and think, this can't work. But it does! Why? Because the following happens:
Total awesomeness. :-) |
Soon after the solution above, I was facing another problem. If I add "application/x-javascript" to the ContentTypesToLocalize then the module is also altering gzip-compressed JavaScript content provided by the ASP.NET AJAX framework. I get error messages like this: "ASP.NET Ajax client-side framework failed to load." in the JavaScript console. Adding the following lines into the web.config file solved the problem:
Is it possible for the module to check whether the content is compressed and only process it when it is not compressed? |
It would help to see the headers for the responses you are working with along with descriptions of the content the response contains. From: krisztianb [mailto:notifications@github.com] Soon after the solution above, I was facing another problem. If I add "application/x-javascript" to the ContentTypesToLocalize then the module is also altering gzip-compressed JavaScript content provided by the ASP.NET AJAX framework. I get error messages like this: "ASP.NET Ajax client-side framework failed to load." in the JavaScript console. Adding the following lines into the web.config file solved the problem: <system.web.extensions> Is it possible for the module to check whether the content is compressed and only process it when it is not compressed? — |
I removed the web.config settings to see the HTTP request and response data. This is the response header:
The response can't be displayed as the browser says "content-encoding error". FireBug shows the following text when I try to access the response tab:
|
Please try the commit just pushed into a new branch called "Dev" and let me know any difference. |
The module crahes at line 121 of LocalizingModule.cs:
Exception:
Looks like that this method is only supported using the pipeline mode of IIS. |
Ok, we seem to have quite a few things different in our set ups what with that error and the x-javascript content-type. If you read the comments above the line that throws you can see the challenge I've had with this. Not sure where to go with this from here. Happy to code any suggestions you may have. |
…e to both IIS integrated pipeline mode and classic mode.
Latest push implements the second suggestion in the SO article. |
The module does not crash any more, but we have the same symptom as in the beginning. The ASP.NET AJAX framework can't be loaded. The gzip response seems to get corrupted by the module. Btw.: I moved the code into our SVN repository and noticed that the "Output path" (Visual Studio, Project preferences..., Build-tab) of the i18n.PostBuild project is not set to "....\bin\lib\net40". So one needs to manually copy it into the bin-folder of the referencing application. The EXE is not part of the NuGet package as it is not found by pack-nuget.bat. Is this intentional? |
It seems that the integrated Visual Studio web server is using IIS classic mode. I tried running the application within an application pool that uses IIS pipeline mode. The problem is gone there and gzip compression is detected correctly. I also tried to reduce the code only to the hack remaining (as the poster says that is works in both modes) and the result is the same. How can we debug the module? The poster says that it should work, so I am interested in finding out why it doesn't work for us. |
Sorry, I don't understand your message. Posters? Hack? Same? From: krisztianb [mailto:notifications@github.com] It seems that the integrated Visual Studio web server is using IIS classic mode. I tried running the application within an application pool that uses IIS pipeline mode. The problem is gone there and gzip compression is detected correctly. I also tried to reduce the code only to the hack remaining (as the poster says that is works in both modes) and the result is the same. How can we debug the module? The posters say that it should work, so I am interested in fining out why it doesn't work for us. — |
Sorry. :-/ The poster is the person who posted the hack at stackoverflow. He said that his hack is working in both modes (IIS classic and pipeline). But it does not work for me in classic mode. Which we wanted it to use for, since there are no problems running the application in piple mode. So it would be a good idea to debug the module in order to find out, what exactly is going on. How can I achieve this? |
The easiest way to debug the library -- or at least the way I do it -- is like this:
The comments in the above mentioned method should be self-explanatory. The Debug output should show in the Debug output window of visual studio. Pleased to hear you are willing to help in this respect. |
In case someone is reading this and has not basic understanding (like me) of how response filters work, I found this nice little tutorial on creating one: http://www.4guysfromrolla.com/articles/120308-1.aspx I fiddled around with the IsResponseCompressed method and the IIS pipeline modes. This is what I found out:
There is no problem in integrated mode, as we already found out. So I tried to find a soultion for classic mode and commented all solutions from this thread you found: http://stackoverflow.com/questions/5434858/can-i-detect-if-content-has-been-compressed-in-my-httpmodule Neither of them work.
It seems to me that we must accept that the filter is not working when the HTTP pipeline is running in classic mode. Maybe something like:
Question 1: However, another idea might be to apply the i18n-module before gzip compression is applied. Do you think this is possible? Question 2: The problem should only occur, when you have set MessageKeyIsValueInDefaultLanguage to true, since this is the option that makes the module remove nugget brackets from the (gzip) output even when there is no translation found, right? |
… gets injected, from ReleaseRequestState to PostReleaseRequestState, that is one event later.
You're right, the best solution is to do the response processing before anyone else. Oddly enough, the way the response filters are chained together, or rather layered together, the last one installed is the first one to get called. So what I've done is try the VERY last pipeline stage that we can install our filter, namely the PostReleaseRequestState. (See remarks section of this page for a full list of all the stages: http://msdn.microsoft.com/en-us/library/System.Web.HttpApplication(v=vs.110).aspx) I've just pushed this mod to the dev branch for you to try. |
I've just tested it. The error is still the same. The link you posted doesn't work. Are you sure about the filter execution order? That really sounds strange. Maybe we could try installing the filter at the beginning of the chain? Just in case the documentation is mistaken. :-) Edit: I modified the title of this issue |
I can't get the URL to work with the markdown here. To get the link to work, replace the %28 with ( and %29 with ). |
Feel free to try the other stages yourself. Hopefully they will work. You can search-and-replace It still could be that the GZIP filter is being installed in the PostReleaseRequestState event, but by a another handler of that event called after our handler. |
I'll happily try several stages. But before I start doing so... Could you give me a list of stages that are worth trying? Unfortunately there are so many stages and I have no real clue about which to use. I've never written an HTTP handler or something similar. Which would be the first stage that we can use to register our module? |
We can register at the very first stage, the BeginRequest event (which we already handle but expect no harm in just adding another handler for that). I don't think it work trying any intermediate ones, but may be wrong. |
I think I will only be able to try this next year. Other more important tasks are at hand. I'll report back. :-/ |
Not sure if this helps, but I was having the same problem. Example response headers that worked versus headers that did not work: Good: HTTP/1.1 200 OK Bad: HTTP/1.1 200 OK I turned off "Enable static content compression" in IIS and that fixed the problem for me. I tried all sorts of combinations of settings from this thread and wasn't able to fix it outside of the IIS setting. Any idea how this Content-Encoding: gzip sneaks its way into the response header? |
Hi Ryan. Make sure that your application pool that contains your application is running in integrated mode. The problem described in this thread only occurs in classic mode. |
I finally had some time to look into the problem. Unfortunately I found no solution for the filter to run before the gzip compression:
Last I found this page: (http://blogs.msdn.com/b/tmarq/archive/2007/08/30/iis-7-0-asp-net-pipelines-modules-handlers-and-preconditions.aspx) that describes the difference between integrated and classic pipeline modes and the possible pipeline stages. Maybe this can help you guys?! I consider this a huge problem. The module must run before gzip compression is applied. Otherwise you can't use compression on content that uses translations/nuggets. :-( |
I am running in Integrated mode and still have the problem. =( |
Sorry I was mistaken. You actually have to disable gzip compression to use the module. For some reason the module gets gzip compressed input (which can't be translated) and has to skip it. Thus your compressed pages are not translated. The only solution I currently see is:
|
@ryan1234: I ran into a similar problem on our live server. JavaScript was served with MIME content type "application/x-javascript" and gzip compression was applied. For this reason the i18n module did not translate the file. Locally IIS serves the JavaScript file with MIME content type "application/javascript" and gzip is not applied. Without any specific configuration from my side. But, I am sure something must be different... The following entry in the web.config file solved both issues (MIME conent type and gzip) on the live server:
I don't understand why, but with this setting gzip compression is no longer applied to JavaScript files (extension .js). Maybe gzip compression is MIME conent type dependent? To summarize: I am serving JavaScript files with MIME conent type "application/javascript" and the i18n module is configured to only run for this JavaScript content type. Not for "application/x-javascript" that is being used for several script files auto-generated by ASP.NET WebForms. Why? See ticket #116. |
Thanks - this was useful. |
I've also encountered problems with gzip compressed .js files. Here are the response headers for bundled javascript files:
and here are the headers for files that are loaded explicitly e.g. @Scripts.Render("~/Scripts/js/test.js")
I have seemingly resolved the issue with changing the default Regex for ContentTypesToLocalize from
to
but this workaround leaves me with .js files not being localized. That's not a big issue for me as I have only a couple strings to localize, but nevertheless it would be nice to have centralized localization. That's just my two cents that hopefully will provide some additional insights to the issue. Thanks for reading. |
This issue is now resolved in a commit in #193 |
Hello, it is me again. :-)
I have a problem with the following .js file:
I checked everything I could:
and still the message is not being translated.
This is the response header:
Do you have any ideas what could possibly be wrong?
The text was updated successfully, but these errors were encountered: