为你的网址提供跨域支持的 JavaScript API

红薯 发布于 2012/08/28 08:35
阅读 6K+
收藏 123

收藏!数据建模最全知识体系解读!>>>

今天我们通过一个简单的例子来讲述如何创建支持跨域调用的 JavaScript API。我相信很多人都尝试实现类似的方法,但可能会遇到很多困难,因为无法通过正常的 AJAX 请求来访问远程服务器并接收响应,这是因为浏览器的安全限制。下面我们将告诉你如何解决这个问题。

完整的示例代码下载:source.zip

一. PHP

首先我们编写一个简单的服务端程序:

<?php

// set possibility to send response to any domain
header('Access-Control-Allow-Origin: *');

if (version_compare(phpversion(), '5.3.0', '>=')  == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE); 

// accept POST params
$sAction = $_POST['action'];
$iParam1 = (int)$_POST['param1'];
$iParam2 = (int)$_POST['param2'];

// perform calculation
$iResult = 0;
switch ($sAction) {
    case 'sum':
        $iResult = $iParam1 + $iParam2;
        break;
    case 'sub':
        $iResult = $iParam1 - $iParam2;
        break;
    case 'mul':
        $iResult = $iParam1 * $iParam2;
        break;
    case 'div':
        $iResult = $iParam1 / $iParam2;
        break;
}

// prepare results array
$aResult = array(
    'result' => $iResult
);

// generate result
header('Content-type: application/json');
echo json_encode($aResult);

值得你关注的是第一行 PHP 代码中的自定义 HEAD ‘Access-Control-Allow-Origin’. 它允许发送回应到任意的服务器,甚至是不同域的。如果你要限制指定域名才能访问,也是在这里设置。接下来是简单的应用逻辑,接受参数并处理请求,这里我们实现的是最简单的加减乘除操作,返回的结果用 JSON 格式。

二. JavaScript

api.js
function do_sum(param1, param2, cfunction) {

    // send ajax response to server
    $.ajax({
        type: 'POST',
        url: 'http://www.script-tutorials.com/demos/301/api.php',
        crossDomain: true,
        dataType: 'json',
        data: 'action=sum¶m1=' + param1 + '¶m2=' + param2,
        success: function(json) {
            // and evoke client's function
            cfunction(json);
        }
    });
}

function do_sub(param1, param2, cfunction) {

    // send ajax response to server
    $.ajax({
        type: 'POST',
        url: 'http://www.script-tutorials.com/demos/301/api.php',
        crossDomain: true,
        dataType: 'json',
        data: 'action=sub¶m1=' + param1 + '¶m2=' + param2,
        success: function(json) {
            // and evoke client's function
            cfunction(json);
        }
    });
}

function do_mul(param1, param2, cfunction) {

    // send ajax response to server
    $.ajax({
        type: 'POST',
        url: 'http://www.script-tutorials.com/demos/301/api.php',
        crossDomain: true,
        dataType: 'json',
        data: 'action=mul¶m1=' + param1 + '¶m2=' + param2,
        success: function(json) {
            // and evoke client's function
            cfunction(json);
        }
    });
}

function do_div(param1, param2, cfunction) {

    // send ajax response to server
    $.ajax({
        type: 'POST',
        url: 'http://www.script-tutorials.com/demos/301/api.php',
        crossDomain: true,
        dataType: 'json',
        data: 'action=div¶m1=' + param1 + '¶m2=' + param2,
        success: function(json) {
            // and evoke client's function
            cfunction(json);
        }
    });
}

这是对服务器端方法的 JS 封装,我准备了 4 个 JavaScript 方法,分别是 do_sum, do_sub, do_mul 和 do_div. 每个方法对应一个服务器的函数。一般来说,首先我们需要设置服务器 API 的 URL,这里是 http://www.script-tutorials.com/demos/301/api.php ,然后需要设置 crossDomain 为 true,最后设置数据格式为 json。请注意第三个参数是 cfunction,这是一个客户端可定制的任意函数用来处理服务器端返回的数据。

三. 使用方法 (客户端)

现在服务器端已经准备好了,接下来看看客户端如何使用这个远程接口。

<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://www.script-tutorials.com/demos/301/api.js"></script>

<script type="text/javascript">
$(document).ready(function() { 

    // execute method 1 (sum) by server
    var param1 = 5;
    var param2 = 10;
    do_sum(param1, param2, function(data) {
        $('#results').append(param1 + ' + ' + param2 + ' = ' + data.result + '
');

        // execute method 2 (sub) by server
        param1 = 25;
        param2 = 15;
        do_sub(param1, param2, function(data) {
            $('#results').append(param1 + ' - ' + param2 + ' = ' + data.result + '
');

            // execute method 3 (mul) by server
            param1 = 8;
            param2 = 5;
            do_mul(param1, param2, function(data) {
                $('#results').append(param1 + ' * ' + param2 + ' = ' + data.result + '
');

                // execute method 4 (sub) by server
                param1 = 33;
                param2 = 11;
                do_sub(param1, param2, function(data) {
                    $('#results').append(param1 + ' / ' + param2 + ' = ' + data.result + '
');
                });
            });

        });
    });
});
</script>

<div id="results"></div>

在这个例子中,我们使用的是服务器端的 JavaScript  函数,我们将上面的代码简化后的结果就是:

var param1 = 5;
var param2 = 10;
do_sum(param1, param2, function(data) {
    $('#results').append(param1 + ' * ' + param2 + ' = ' + data.result + '
');
});

我们传递了三个参数,包括两个数字和一个函数引用,我们将在这个函数中接收到服务器的回应信息,然后可将它们显示出来。

结论

希望这个例子足够简单清晰,试试吧?

英文原文OSCHINA原创翻译

加载中
0
景愿
景愿
果断插一句, 对于服务器不能访问外网的情况,完全不适用 
0
Sephiroth
Sephiroth
要是JS能直接跨域就好了
0
y
yumearzus

yahoo提供一个服务,可以把网站数据转化成可跨域读取的格式.

0
john_sh
john_sh

引用来自“Liuxey”的答案

果断插一句, 对于服务器不能访问外网的情况,完全不适用 
以回调函数的方式也不可以?
景愿
景愿
就红薯说的这个方法,是走后代代理,如果禁止访问外网,肯定是不行的。如果跨的域受你控制,加回调当然没问题,
0
0
Junv
Junv

header('Access-Control-Allow-Origin: *'); 使用这个,安全性得不到保障,后台获取不到前台的cookie信息。它是匿名的。不建议对个人隐私数据也这样做。

http://toozhao.com/2012/08/java-cors-cross-domain-request/

0
h
huxiaoqi
jsonp跨域不就OK了么
0
owen.chen
owen.chen

引用来自“john.liao”的答案

引用来自“Liuxey”的答案

果断插一句, 对于服务器不能访问外网的情况,完全不适用 
以回调函数的方式也不可以?
如果真的遇到这样的情况.若真要这么麻烦.我宁愿写PHP的API接口
0
废柴大叔
废柴大叔
我宁愿直接用后台a.php抓取接口 然后用js引用我的a.php 照样可以算是跨域访问.
0
废柴大叔
废柴大叔
一般跨域访问的数据 都不会太大 所以就算后台抓取 也不会消耗什么性能
返回顶部
顶部