Closed figuerres closed 7 years ago
I guess to have a better idea of why and where it is happening is to put some console logging down the Observable chain (before appending headers).
You might also look into .catch()
observable operators used along the way - maybe somewhere you suppressing an error and so it not visible.
Also if you can provide a plunkr that would be great because I've used this lib in IE11 as well and it was working fine so maybe you have some special use case.
what i have found so far is this:
the script runs that is adding the header in the browser. Fiddler trace shows that the header is not present. happens (as far as i can tell) when the code is from localhost / debug or my loading the app from a server.
i have code in app.component constructor that sets up the interceptor
constructor( private route: ActivatedRoute, private router: Router, private authService: AuthService, private menuService: MenuDataService , private http: Http, private httpInterceptor: HttpInterceptorService, ) { httpInterceptor.request().addInterceptor((data, method) => { const headers = getHttpHeadersOrInit(data, method); // Get or create header and set back on
data console.log("AppComponent this.authService ", this.authService ); console.log("AppComponent this.authService.loggedIn ", this.authService.loggedIn ); if( this.authService.loggedIn ){ console.log("AppComponent this.authService ", this.authService ); console.log("AppComponent this.authService.currentUser ", this.authService.currentUser); if( this.authService.currentUser ){ headers.append('Authorization', this.authService.currentUser.token_type + " " + this.authService.currentUser.access_token); console.log("token " , this.authService.currentUser.token_type + " " + this.authService.currentUser.access_token ); } } console.log(method, data); return data; }); }
the console.log calls all look normal in IE 11, no error other than the 401 result.
I will take a second look tomrrow and see if i can get more details.
I may have this figured out, will need to setup a test today and see what happens. has to do with how chrome and edge do the OPTIONS call. but IE 11 I do not see that call.
then i got to thinking about old web sites and that i have seen the header "WWW-Authenticate" in the past.
possibly IE 11 is looking for that stuff before it will send the token to the server ??
i added the www-auth header and no change. i thought that my not sending that header was the problem but it does not seem to make a difference.
Well I can only suggest you to create a plunkr so I can have a look.
will see what i can do, my app has multiple servers and is inside a private network, so a little complicated for me to replicate. is there a token server that i can test against ?? i will see if i can find one...
Maybe if you have different servers most probably they are on other domain and if so you have to deal with CORS policy where server should tell which headers it allows client to send. I'm not sure how exactly CORS are implemented in IE11 but it might just remove some headers silently...
that is part of what i suspect is happening..... i am checking for what is going on and making a small test case, i did find an oath test server i may be able to use and test with. will let you know when i have more info.
i am trying to make a working plunk for IE but having some issues. it works in chrome but hangs in IE due to some missing poly fill or something. https://plnkr.co/edit/MX7j8Brm0tzQEVKzMCAs
i hard coded a token that works right now and pointed the code to my service.
if you can make this work in IE 11 try any service that needs a token....
ok so i am fail at plunker .... here is a link: https://github.com/figuerres/ie11test
angualr cli - current packages.
i can update the token a few times if you want to test with my service....
the project loads and runs in chrome and in IE 11 , but in IE 11 it fails to get the data with a 401 status as the token is never sent to the web service.
almost no code; just trying to add the auth header.
simple jquery works, so something in the angular / typescript seems to be failing. kind of thought so but just tested to see what happens. i wonder if there is a change in the angular http that breaks on IE 11 ?
I will have a look to your plukr later. Regarding angular's http library it's unlikely that something is breaking in IE because they are testing angular in saucelabs in IE as well so...
thanks, i am going to try and see if i can figure out any more, i saw that the code to add the header was called in IE in my angular cli project so possibly the proxy ??
or in IE 11 something is not initialized right ??
i did a test of some code and i found this, not much but it might help:
if i use your library to watch the traffic but not modify the headers and i make an http post and add my own RequestOptions object with the header that works.
when i add a header with the ..... i think i found something .....
wow ok this is nuts and now i have to figure out how to bet handle this.....
IE 11 seems to need to have the http request options set or it fails. this has not been a problem with chrome or with edge!
in my githhub code i added
var options = new RequestOptions({ withCredentials:true });
and then
this.http.post( 'https://devwebservice.adldelivery.com/api/SSRS/ListItemTypes','',options).subscribe(r => this.res = r.text());
and it works!!
i will take a look at your code and see if i can do that in the interceptor setup.... or if some other thing needs to be done.
works in a test case but not in my actual app code.... no idea why that is happening now.
Ah, of course you have to set that flag, because you trying to send authorization headers. According to MDN:
The XMLHttpRequest.withCredentials property is a Boolean that indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-site requests.
So it shouldn't had been working even in chrome... A bug?!
Anyway you can set withCredentials flag from the interceptor, you can use some helper function to get Options from data and then set the flag.
you may be right! i just knew that the app had been working for me with chrome and we have been testing IE 11 to get ready for a limited test release to dogfood some of the work we have so far....
and then i started down this rabbit hole ....
right now the main app is not working and i am going between the test code and the main app code and checking them. there may be a package having a side effect in the main app code.... more fun to trace down.
@gund
Hey I think i have found a very odd bug but i am not 100% sure if this is with the code or with the way IE11 handles javascript data or what.
only in IE11 do i see this happening.
if the http call starts without an Options Arg then the token is not sent to the server even though the code seems to be creating the headers collection and adding them to the options . if i initialize the http call with an empty request options arg with nothing set then it works like it does in chrome. something about the data[] array / collection and modifying it going wrong on IE 11
i am looking at your code that gets the options from the array and playing with it to see if i can make it work on IE 11 .
seems odd, possibly some side effect of angualr cli ? i do not know for sure but it is happening and it is related to the options being in the http call before the interceptor gets into it.
ok more details .... if the http.post . does not have options args set then the data arguments has a size of 2 with arg 0 and arg 1 but no arg 2 for the options in IE 11 the line that tried to set the options is setting data[2] but there is not data[2] in the arguments collection and arguments is not a true array and does not support slice/push/pop on chrome it seems to allow adding an argument on the fly but on in IE 11 so the local variables are there but not added to the actual arguments that get passed back up the chain to the final call to http / ajax.
what i am doing in my code that is working in y test app and i will test this next in my main app is to do an Array.from(data)
then i can call temp.splice(idx,0,options); and then data = temp
now the new options and headers are added and the call works.
so possibly this code: https://github.com/gund/ng-http-interceptor/blob/master/src/http/helpers/getHttpHeadersOrInit.ts
// Set Options back data[idx] = options;
should be changed to work that way ??
Interesting finding, I don't remember that I checked the type of the arguments...
They are actually coming from the Proxy here.
Can you try to log the type of arguments in request interceptor in IE?
Alright I just checked in IE and can confirm that Proxy polyfill returns Arguments Object instead of Array. As a quick fix you can add in your request interceptor next line:
httpInterceptor.request().addInterceptor(data => Array.prototype.slice.call(data));
This will ensure that data is always Array no matter what.
This is only required if you ever going to use Proxy polyfill, so I'm not sure if I will add this piece of code to this library. It should probably be in polyfill itself...
Crazy little detail for sure, took a bunch of tries to fully get at what was going on. At least now we know and can at least put a note in the docs for anyone who has to support ie. Also I let some folks at Microsoft know so they can also document the issue from the ie quirks side of things. My boss was glad I was able to get it to work as we have customers still on ie 11 and Windows 7 along with some older pc in our warehouses.
this may not be an issue with the code in this package but i am putting a message here in case anyone knows what this is and how to fix it.
i have an app that is working 100% in chrome and Edge. basic page load works in IE 11
web service calls that need a JWT fail.
IE 11 is not giving any errors during the app load.
the app is using the current angualr 4.xxx packages and is built with angualr-cli into packed scripts.
i am trying to determine the cause but right now i have no idea what the real problem is.