• Crossdomain AJAX with JSONP great article


    Cross-domain AJAX with JSONP - Devlog

    Anyone who develops Javascript long enough undoubtedly runs into difficulties involving the various security features all browser vendors implement. These security features are a good thing -- they protect us from malicious users hijacking our browsing experience. But they can certainly cause some headaches. The security feature that presents the most difficulty for us as developers is the same origin policy.

    In a nutshell, this policy prevents pages from two different domains from modifying each others properties, using XMLHttpRequest, setting cookies etc. For instance, Example.com and OtherExample.com can't get references to each others document properties and can't set cookies on each other. Additionally, Example.com can't use XMLHttpRequest (aka AJAX) to load a resource from OtherExample.com. This last bit is probably the biggest issue for developers today -- in todays world of open web services and mashups. How do you consume a web service with Javascript if you can't load the data properly?

    Solution 1: Use a server-side proxy

    The first way around this problem is to use a very simple server-side script that acts as a proxy to the web service. So instead of requesting AJAX from the remote site, you request it locally on your own domain through the proxy. The proxy itself has it's programming logic to send your request off to the remote site, gather the data, and then serve it back to you.

    .________________________.
    | Client on YourSite.com |
    '-\/---------/\----------'
      ||         ||
      ||_________||__.
      | AJAX Request |
      '---\/-----/\--'
          ||     ||
          ||_____||______________.
          | YourSite.com         |
          | (Ex. ajax_proxy.php) |
          '---\/-----/\----------'
              ||     ||
              ||_____||__________.
              | OtherSite.com    |
              '------------------'

    Since your server-side script has no qualms about fetching data from another domain, you can successfully proxy all AJAX like this without running into any trouble. And then since the client browser is fetching the data from the local domain (even though you're making another request behind the scenes), it doesn't violate the same origin policy.

    An example proxy script might look something like this (maybe a little more complex if you're handling POST data too):

    1. $url = 'http://othersite.com/someservice?' . http_build_query($_GET);

    Remember, the sole purpose of the proxy is just so the client browser can load the data locally on the same domain so the same origin policy isn't violated.

    Drawbacks

    This method works well but has two obvious drawbacks. First is of course that you need a server-side script at all. Especially if you are providing a service, this raises the barrier for entry and makes it harder for "noobs" to use your widget -- it's not a simple "paste this code into your footer" instruction; you also need to explain how to install the proxy service.

    The second drawback is that your own servers are making these requests which makes the whole process slower, but also eats up your resources -- both your processing power and even just simple bandwidth.

    Solution 2: JSONP

    The second solution is to use JSONP -- "JSON with Padding." This is a technique that lets you get around the same origin policy. In order to use JSONP, the service you are requesting needs to support it.

    So in the last solution, the consumer (the user using the service) required an ajax_proxy.php or whatever server-side proxy script. In this solution, the provider (Digg, Amazon, Yahoo -- whatever) needs to support JSONP themselves. Thankfully, these days the idea is catching on and it's likely JSONP is an option. And if you're a service provider, then you'll want to build it in to your service for sure.

    How it works

    A normal JSON request is sent using XMLHttpRequest and the reply looks something like this:

    Plain TextJAVASCRIPT:
    1. {'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'}

    Now the truth is, JSONP isn't AJAX at all technically speaking because it does not use XMLHttpRequest. JSONP requests are made by dynamically inserting a <script> tag into the DOM. For example, you'd insert this:

    1. <script type="text/javascript" src="http://othersite.com/service?all=your&params=as&usual=gohere"></script>

    Then that remote Javascript file is loaded and contains an actual Javascript function call. For example:

    Plain TextJAVASCRIPT:
    1. handleJsonReply({'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'});

    In other words, instead of reading AJAX data directly into a variable in Javascript, you define a callback function that is called when the data arrives, and the first parameter is the data itself as an object literal. If you were a provider implementing JSON on your service you might have something like:

    1. // A service provider accepts a 'callback' parameter
    2. // that it uses to wrap an AJAX reply
    3.  
    4. // Imagine we did some work here
    5. $json = json_encode($mydata);
    6.  
    7. // Using JSONP
    8. if ($_GET['callback']) {
    9.     echo $_GET['callback'] . "($json);"; // somefunction({data here});
    10.    
    11. // Normal JSON
    12. } else {
    13.     echo $json;
    14. }

    The Javascript source code result of that request is nothing but a real executable function call with a Javascript object literal. It's as if you added the tag yourself and it called some functions -- the difference being that the JS is written by the producer on-the-fly and embeds the data you want right in the code. This is why it all works; it's not actually AJAX at all, it's just loading a remote Javascript file that happens to have some useful data in it.

    Using a library like jQuery that supports JSONP, these details of inserting the special script tag and creating the special callback function are all taken care of automatically. Using a JS library, usually the only difference between JSONP and real AJAX is that you enable a 'jsonp' option.

    Drawbacks

    The first limitation to this method is that you have to rely on the provider to implement JSONP. The provider needs to actually support JSONP -- they need to wrap their JSON data with that callback function name.

    Then the next limitation -- and this is a big one -- is that JSONP doesn't support POST requests. Since all data is passed in the query string as GET data, you are severely limited if your services require the passing of long data (for example, forum posts or comments or articles). But for the majority of consumer services that fetch more data than they push, this isn't such a big problem.

    JSONP with jQuery

    Step 1: Make sure the provider supports JSONP.

    Step 2: Set the dataType option to jsonp, and if the provider uses a different GET param other than 'callback', specify the jsonp option to that parameter name.

    Plain TextJAVASCRIPT:
    1. $.ajax({
    2.     // ... Use the AJAX utility as you normally would
    3.     dataType: 'jsonp',
    4.     // ...
    5. });

    jQuery will generate a unique callback name for this request (something like json1268267816). Thus, the reply from a web service would be something like:

    Plain TextJAVASCRIPT:
    1. json1268267816({'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'});

    But jQuery handles it all seamlessly, so you as the developer just handle it like a normal AJAX request using the same jQuery success/failure/complete callback hooks.

  • 相关阅读:
    【工具类】图片压缩工具类,可压缩jpg, png等图片
    【Nginx用法】nginx location正则表达式写法,详解Nginx location 匹配规则(很详细哦)
    【Nginx异常】[error] 4236#29900: OpenEvent(“Global gx_reload_27128“) failed (5: Access is denied)
    【Nginx异常】Nginx启动一闪而过没反应,Nginx双击打开后,没有启动成功,也没有进程,且127.0.0.1:8080访问不到
    开启vue-element-ui打包生成报告
    Cas 5.2.x 使用 实现SSO单点登录的问题
    springmvc在使用@ModelAttribute注解获取Request和Response会产生线程并发不安全问题
    企业微信会话存档开发与问题
    高手怎么查找CPU过高的Java代码。具体到行
    ubuntu中清除开始菜单中的应用图标
  • 原文地址:https://www.cnblogs.com/lexus/p/2489472.html
Copyright © 2020-2023  润新知