关于javascript的跨域问题


这个问题以前也遇到过,也是网上搜答案解决的。今天在前端群里看到有新手问这种问题。。话说不如自己上网搜啊,网上很多现成的。

今天,自己总结下吧,搜到这篇也是咱两的缘分,虽然不太可能,我的站还没被百度收录呢。

01


什么是跨域?

参考这篇文章的: 什么是跨域?怎么解决跨域问题?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

所谓同源是指: 域名、协议、端口均相同,不明白也没关系,举个栗子。

http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456, 跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意: localhost 和 127.0.0.1 虽然都指向本机,当也属于跨域。

ajax或者iframe指向的地址中,二级域名、端口、协议必须与主页面完全相同,否则就算跨域 —— 知乎用户一线希望的回答。


跨域的三种解决方案

先做点准备工作。

www.test.com/cos.html

TIM图片20170726154126


请求的客户端地址:www.web.com/index.php

仅演示只写两行代码

$a = $_REQUEST['a'];
echo json_encode(['a'=>$a]);


初始情况下,访问cos.html的话因为域名不一致,存在跨域,所以ajax不执行,且报错:

XMLHttpRequest cannot load http://www.web.com/index.php?a=true. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://www.test.com' is therefore not allowed access.


以下为常用解决方式:

1. 通过jsonp跨域

在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。

在cos.html的js部分改为

TIM图片20170726160002

因为用这种方式,无法传递post参数,只能用get方式传递数据。

在服务端的代码也得进行处理:

error_reporting(0); #关闭错误提示 notice什么的很烦
$callback = $_GET['callback'];//得到的回调函数
$a = $_REQUEST['a'];
echo $callback.'('.json_encode(['a'=>$a]).')';//输出

结果如下: 引入文件返回 jsonp_callback({"a":"true"}) 就是执行jsonp_callback这个我们之前写好的函数。成功打印出了结果。

tip: 这种方式只支持 get 方式的请求,而且客户端和服务端均要改动,比较麻烦,不建议使用。


2. 使用代理

我还是直接黏贴上面引用文章的解释,说的很明白了。

例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题


3. 服务端输出前处理http header头

这种方式就是我现在在用的了,客户端什么都不需要修改,也没有中间的代理层,直捣黄龙。。

先将cos.html还原成最初始的状态,然后修改服务端代码,在输出前修改http header头,这里以php举例:

header('Access-Control-Allow-Origin:http://www.test.com');//仅允许http://www.test.com来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
$a = $_REQUEST['a'];
echo json_encode(['a'=>$a]);

成功返回数据。

tip: 第一个来源访问域名的设置,也可以使用通配符(*)表示所有站点。


javascript php


上一篇:计算机组成原理(一)

在虚拟机中安装centOS操作系统:下一篇