• 0

JQuery, XmlHttpRequest, the OPTIONS verb and Mr. Preflight


Question

Even confident developers get stuck sometimes!

I've recently been doing some Cross-domain javascript using JSONP, and ASP.NET MVC.

The particular Controller action will only respond to a POST request, this is by design.

In IE8, I can see (via Fiddler2) that the response is correct, and returning a HTTP 200 response, along with the JSONP javascript.

In Firefox, Safari and Chrome, the response is still being returned, with the appropriate HTTP 200 code and JSONP content, the only difference is that the XmlHttpRequest object being used by JQuery is setting the status code to 0, and the responseText to empty.

Originally, I thought this was due to COR HTTP Preflighting (Http Access Control), whereby a custom header or a content-type other than text/plain would cause an additional HTTP request (with an OPTIONS) verb to be sent to the server. I can see in Fiddler2 that the OPTIONS request is being responded to with a HTTP 404.

The web server is IIS7 (but the production web server will be an IIS6 box). In IIS7, I can see the standard OPTIONSVerbHandler listed in the handlers, but I'm not convinced this is actually doing anything (in fact, I can't even find any documentation about the OPTIONSVerbHandler anywhere).

To get round this, I modifed the JQuery library to not set the custom header, and change the content-type to text/plain instead of application/json, and Firefox finally starts bypassing the OPTIONS request, and just plain POSTs.

The problem still lies in an empty response (according to the XmlHttpRequest object), even though Fiddler2 shows that a successful HTTP 200 response, with content is being returned.

Any help?

7 answers to this question

Recommended Posts

  • 0

It appears to be part of the design of the jQuery library. Checking through the source (v1.3.2), it only does a JSONP callback via the script tag with the Http type set to GET (which actually makes sense), switching to a GET instead of POST resolves the issue.

  • 0
  Antaris said:
It appears to be part of the design of the jQuery library. Checking through the source (v1.3.2), it only does a JSONP callback via the script tag with the Http type set to GET (which actually makes sense), switching to a GET instead of POST resolves the issue.

Good to know. I'll jot that one down. :)

  • 0
  Antaris said:
Even confident developers get stuck sometimes!

I've recently been doing some Cross-domain javascript using JSONP, and ASP.NET MVC.

The particular Controller action will only respond to a POST request, this is by design.

In IE8, I can see (via Fiddler2) that the response is correct, and returning a HTTP 200 response, along with the JSONP javascript.

In Firefox, Safari and Chrome, the response is still being returned, with the appropriate HTTP 200 code and JSONP content, the only difference is that the XmlHttpRequest object being used by JQuery is setting the status code to 0, and the responseText to empty.

Originally, I thought this was due to COR HTTP Preflighting (Http Access Control), whereby a custom header or a content-type other than text/plain would cause an additional HTTP request (with an OPTIONS) verb to be sent to the server. I can see in Fiddler2 that the OPTIONS request is being responded to with a HTTP 404.

The web server is IIS7 (but the production web server will be an IIS6 box). In IIS7, I can see the standard OPTIONSVerbHandler listed in the handlers, but I'm not convinced this is actually doing anything (in fact, I can't even find any documentation about the OPTIONSVerbHandler anywhere).

To get round this, I modifed the JQuery library to not set the custom header, and change the content-type to text/plain instead of application/json, and Firefox finally starts bypassing the OPTIONS request, and just plain POSTs.

The problem still lies in an empty response (according to the XmlHttpRequest object), even though Fiddler2 shows that a successful HTTP 200 response, with content is being returned.

Any help?

Thread bump!

Would you mind showing me how you modified jquery to not send the OPTIONS verb in Firefox? I have the same problem as you did. Either that, or getting IIS to understand the OPTIONS verb

  • 0

Hi,

The modification was actually not required. When you make a JSONP call, it actually achieves the cross-domain transparency by creating a new SCRIPT element on the page. Because you can't make a POST call from a SCRIPT element (it's only ever a GET), simply changing your POST to a GET will stop Firefox sending the OPTIONS header ahead for validation.

  • 0
  Antaris said:
Hi,

The modification was actually not required. When you make a JSONP call, it actually achieves the cross-domain transparency by creating a new SCRIPT element on the page. Because you can't make a POST call from a SCRIPT element (it's only ever a GET), simply changing your POST to a GET will stop Firefox sending the OPTIONS header ahead for validation.

So you're saying a cross domain POST is impossible using jQuery? My issue is that using a GET, I have to put the parameters in the querystring which I didn't want to do as that stuff will not be encrypted. (I was planning on POST'ing to an HTTPS site with authentication info). While developing I hosted the webservice on the same site and I was able to POST to it using $.post and sending the result to a callback. Now that it's been tested I moved the webservice over to HTTPS and herein lies the problem.

  • 0
  pio!pio! said:
So you're saying a cross domain POST is impossible using jQuery? My issue is that using a GET, I have to put the parameters in the querystring which I didn't want to do as that stuff will not be encrypted. (I was planning on POST'ing to an HTTPS site with authentication info). While developing I hosted the webservice on the same site and I was able to POST to it using $.post and sending the result to a callback. Now that it's been tested I moved the webservice over to HTTPS and herein lies the problem.

There is the problem though. You can't do a POST from a SCRIPT element. The browser will see the url that is set as it's source, and do a GET request on that, just like it would in any other resource (such as other SCRIPTS and LINKS [stylesheets]). The thing which will confuse many people, is that because they are actually doing the JSONP action via JQuery's ajax call, they assume its being done via XmlHttpRequest. It's not actually doing this, it's simply telling the browser there is another script to load. The way JSONP works, is that you pass a callback function name to whatever service you are dynamically calling, and that service has to wrap the JSON serialised data in that function call which allows it to evaluated at the client browser, e.g.:

GET http://somedomain.com/someservice/getMeSom...back=function01

Which should return it's serialised data something akin to:

function01({ data: { name = "Test", age = 25 }});

The browser succesfully returns that data because its a GET request across domains (which is allowed), and executes that function 'function01'.

Now, with the JSONP datatype, jquery automatically generates that callback function and name (this is overridable) and transparent handles this for you.

Unforetunately, you can't do this via POST. Hope that clears up the confusion somewhat.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Microsoft: Edge performs better than Google Chrome on Windows in ad blocking and more by Sayan Sen Recently, Google put out a performance report for its Chrome web browser explaining how the changes it made to memory management and caching mechanisms managed to make it the fastest it has ever been. Google is not the only one to do it recently, as Microsoft too made similar claims about performance boosts earlier in the year in April. If you were trying to pick between the two, Microsoft is trying to make it easy for you to decide. In a recent blog post titled "Microsoft Edge browser: The fast, smart alternative to Chrome," the tech giant has laid out all the reasons you should pick its browser over Google Chrome. As pointed out in our first paragraph, performance is something these companies often try to brag about, and for good reasons, because people do want to get a snappier experience. This could explain why Mozilla's Firefox has been left behind over time in terms of market share, as it has not been able to keep up with Chromium-based browsers in the performance department. Microsoft says that Edge is better for your Windows PC than Google's Chrome, as it is a "Microsoft product" that "integrates closely with Microsoft Windows," which helps with "performance benefits." Besides that, the Redmond company also points out other "speed and efficiency" features of Edge, like sleeping tabs that helped save 'over 7 trillion megabytes of memory' in 2024. And Edge is also said to "help with smooth performance so that add-ons like Microsoft Translator, ad blockers, and password managers work efficiently." Microsoft adds how the "optimized architecture of Edge helps with lower CPU load and overall resource consumption, providing a smooth experience, particularly on low-spec devices" and also how its "efficient resource allocation helps minimize slowdowns." Aside from performance, productivity is another area where Microsoft says Edge excels. That is thanks to Microsoft 365 integration and other AI tools. In the end of the blog post, Microsoft suggests that this is the right time to switch to Edge from Google Chrome. You can find the post here on Microsoft's official website.
    • At some point, hardware becomes obsolete and we cant blame vendors for dropping support. Much of the models dropped, run Intel hardware which means they can install something else on the device if they truly want to keep using it.
    • Well, that was fun: PS C:\WINDOWS\system32> Install-Script -Name Set-InetpubFolderAcl WARNING: Unable to download from URI 'https://go.microsoft.com/fwlin...627338&clcid=0x409' to ''. WARNING: Unable to download the list of available providers. Check your internet connection. PackageManagement\Install-PackageProvider : No match was found for the specified search criteria for the provider 'NuGet'. The package provider requires 'PackageManagement' and 'Provider' tags. Please check if the specified package has the tags. At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7468 char:21 + ... $null = PackageManagement\Install-PackageProvider -Name $script:N ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (Microsoft.Power...PackageProvider:InstallPackageProvider) [Install-PackageProvider], Exception + FullyQualifiedErrorId : NoMatchFoundForProvider,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackageProvider PackageManagement\Import-PackageProvider : No match was found for the specified search criteria and provider name 'NuGet'. Try 'Get-PackageProvider -ListAvailable' to see if the provider exists on the system. At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7474 char:21 + ... $null = PackageManagement\Import-PackageProvider -Name $script:Nu ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (NuGet:String) [Import-PackageProvider], Exception + FullyQualifiedErrorId : NoMatchFoundForCriteria,Microsoft.PowerShell.PackageManagement.Cmdlets.ImportPackageProvider WARNING: Unable to download from URI 'https://go.microsoft.com/fwlin...627338&clcid=0x409' to ''. WARNING: Unable to download the list of available providers. Check your internet connection. PackageManagement\Get-PackageProvider : Unable to find package provider 'NuGet'. It may not be imported yet. Try 'Get-PackageProvider -ListAvailable'. At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:7478 char:30 + ... tProvider = PackageManagement\Get-PackageProvider -Name $script:NuGet ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Microsoft.Power...PackageProvider:GetPackageProvider) [Get-PackageProvider], Exceptio n + FullyQualifiedErrorId : UnknownProviderFromActivatedList,Microsoft.PowerShell.PackageManagement.Cmdlets.GetPackageProvider Install-Script : NuGet provider is required to interact with NuGet-based repositories. Please ensure that '2.8.5.201' or newer version of NuGet provider is installed. At line:1 char:1 + Install-Script -Name Set-InetpubFolderAcl + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: ( [Install-Script], InvalidOperationException + FullyQualifiedErrorId : CouldNotInstallNuGetProvider,Install-Script
    • Because Apple has never discontinued Mac models before now?
  • Recent Achievements

    • Week One Done
      abortretryfail earned a badge
      Week One Done
    • First Post
      Mr bot earned a badge
      First Post
    • First Post
      Bkl211 earned a badge
      First Post
    • One Year In
      Mido gaber earned a badge
      One Year In
    • One Year In
      Vladimir Migunov earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      488
    2. 2
      +FloatingFatMan
      257
    3. 3
      snowy owl
      247
    4. 4
      ATLien_0
      222
    5. 5
      +Edouard
      191
  • Tell a friend

    Love Neowin? Tell a friend!