YanTianFeng的知识库

Want Coding

Want Reading

文章 89

访问 18444

评论 2

头像

YanTianFeng

发私信

文章 89
访问 18444
评论 2
JAVASCRIPT
返回顶部

Knowledge  跨域解决方案

标签   JavaScript   Ajax  

  ( 331 )       ( 1 )


前言

我们经常会在页面上使用 ajax 请求访问其他服务器的数据,此时,客户端发送的请求就属于跨域请求 . 实际应用中,成功发送一个跨域请求有一定要求,今天我们就来了解一下这些要求。

HTML 中支持跨域的标签



让 JavaScript 支持跨域的其他方式

《 1 》 jsonp 方式实现跨域(以 php 为例)

有些网站出于安全考虑, 不会设置允许跨域, 而我们又刚好需要用到一次跨域请求, 那么, jsonp 就派上用场了:

现在问题来了?什么是 jsonp ?维基百科的定义是: JSONP ( JSON with Padding )。 JSONP 也叫填充式 JSON ,是应用 JSON 的一种新方法,只不过是被包含在函数调用中的 JSON ,例如:

callbackfunction({"name","trigkit4"});

JSONP 由两部分组成:回调函数和 JSON 数据。回调函数是当响应到来时应该在页面中调用的函数,而 JSON 数据就是传入回调函数中的参数。

php 代码:

$callback = $this->request->param('callback');
$employees = ["employees"=>
                   [ ["id"=>10001, "name"=>"马云", "age"=>"88", "job"=>"CEO", "salary"=>"10000万", "isAdmin"=>true, "entryTime"=>"2001-10-1 17:05"],
                    ["id"=>10002, "name"=>"马化腾", "age"=>"77", "job"=>"CEO", "salary"=>"10000万", "isAdmin"=>true, "entryTime"=>"2002-10-2 17:05"],
                    ["id"=>10003, "name"=>"李彦宏", "age"=>"66", "job"=>"CEO", "salary"=>"10000万", "isAdmin"=>true, "entryTime"=>"2003-10-3 17:05"],
                    ["id"=>10004, "name"=>"老马", "age"=>"28", "job"=>"web前端高级软件开发工程师", "salary"=>"10000万", "isAdmin"=>false, "entryTime"=>"2004-10-4 17:05"],
                    ["id"=>10005, "name"=>"老张", "age"=>"26", "job"=>"web前端高级软件开发工程师", "salary"=>"10000万", "isAdmin"=>false, "entryTime"=>"2005-10-5 17:05"]
                  ] ];
$d = json_encode($employees);
echo $callback.'('.$d.')';

这段 php 代码清晰展示了后台语言做了哪些操作。只是个例子,无法直接拷贝使用,前端开发人员可以忽略。

访问:

这里正是利用了 script 标签本身支持跨域访问资源的特性,因此完成了跨域。

请求响应为:

hello( { employees: [ { id: 10001, name: "马云", age: "88", job: "CEO", salary: "10000万", isAdmin: true, entryTime: "2001-10-1 17:05" }, { id: 10002, name: "马化腾", age: "77", job: "CEO", salary: "10000万", isAdmin: true, entryTime: "2002-10-2 17:05" }, { id: 10003, name: "李彦宏", age: "66", job: "CEO", salary: "10000万", isAdmin: true, entryTime: "2003-10-3 17:05" }, { id: 10004, name: "老马", age: "28", job: "web前端高级软件开发工程师", salary: "10000万", isAdmin: false, entryTime: "2004-10-4 17:05" }, { id: 10005, name: "老张", age: "26", job: "web前端高级软件开发工程师", salary: "10000万", isAdmin: false, entryTime: "2005-10-5 17:05" } ] } )

可以看出,响应格式为: hello( json 数据 ) ; 这是一个标准的 js 函数调用语句。 于是乎, 在 js 中我们只需要定义一个同名的 js 函数就可以了:

function hello(data)
{
     console.log(data);
}

这个函数被调用时,参数部分传入的就是从其他域获取的数据,至此,跨域资源共享已经实现。

JSONP 的优点:它不像 XMLHttpRequest 对象实现的 Ajax 请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。

JSONP 的缺点:它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求;它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript 调用的问题。

《 2 》在后端程序中设置响应头(以 php 为例)

代码如下:

//允许从 yantianfeng.com 发起的跨域请求
header("Access-Control-Allow-Origin: yantianfeng.com");

//如果需要设置允许所有域名发起的跨域请求,可以使用通配符 *
header("Access-Control-Allow-Origin: *");

这种设置是由后端开发人员操作的,无需前端配合;对于前端开发人员来说就是福音,前端无需做任何配置、准备,正常请求数据即可完成跨域。

当然,如果希望 整个网站允许跨域请求,可以参考第三种设置:

《 3 》在服务器中设置响应头(以 IIS 为例)

打开 IIS ,找到 "HTTP 响应标头 " 点进去,在右侧可以看到【添加】按钮,点击添加并加入如下标头即可:

Access - Control - Allow - Headers : Content - Type , api_key , Authorization

Access - Control - Allow - Origin :*

效果如下: