Yii2.0 探究五:基于Yii2.0框架的Restful Api的对接以及跨域解决
基于Yii2.0框架的Restful Api的对接以及跨域解决;
2.新建api模块,专门用来存放api相关,并配置响应格式为json而不是xml;
3.改造请求错误提示为Json格式,而非html;
4.测试调试请求;
5.前端进行接收,这部分我们说下前端ajax如何跨域做出请求;
准备:
1.新建news表用来展示(也可以用命令行migration去建表):
2.api的请求工具:chrome中建议安装postman、firefox中安装HttpRequest,其他浏览器自行解决;
3.Json的查看工具:chrome中建议安装JSONView,会显示格式化的json,firefox中安装jsonformater,其他浏览器自行解决;
3.开启伪静态rewrite、并且配置api的二级域名为api.news.com格式,绑定在api/web下面;
1.copy一份frontend或backend目录下的文件重命名为api放置在同级下作为api的内容,在common>bootstrap.php文件中依赖注入声明api模块:
Yii::setAlias("@api",dirname(dirname(__DIR__))."/api");
2.在api下新建v1、v2作为我们不同版本的内容、并在里面新建controllers、models、views部分,并分别在v1、v2下新建Module.php声明命名空间;
3.api文件夹相关命名空间可自行修改,这里我们要对配置文件作出修改:
4.新建api>modules>v1>controllers>NewsController控制器用来响应,并重写behaviors响应为json:
5.新建model在api>modules>v1>modles>News.php,可采用gii生成;
以上就是api模块建立的过程;
1.在common>controllers>ErrorAction.php去重写action错误的提示;
这里我们做出错误请求,api.news.com/v3你会发现,提示Json数据为
{status: "error", code: 404, msg: "页面未找到。"}
这在api请求错误时很有帮助;
1.在数据表news中插入数据
2.在postman中我们输入http://api.news.com/v1/news会显示出news的数据;
3.格式:一般Restful Api的格式是固定的;当然也可以去重写;
GET http://api.news.com/v1/news 列出所有新闻
GET http://api.news.com/v1/news/1 列出id为1的新闻
POST http://api.news.com/v1/news 新建新闻
DELETE http://api.news.com/v1/news/1 删除id为1的新闻
PUT/PATCH http://api.news.com/v1/news/1 修改id为1的新闻
我们可以在postman中输入以上url做测试,其他方式例如OPTIONS、HEAD可寻找资料或查看手册;
以上我们就搭建完成了Restful api的接口;
前面:前端所有部分都通过jquery来做ajax请求;
事实上我们只需要一个button按钮来测试我们所得到的数据;
在frontend.news.com中新建一个action并render一个视图我们用来测试
当你在frontend.news.com用ajax去请求我们api.news.com的api接口时候,你会发现:请求失败,并报错,原因是跨域,浏览器做出了限制;
也就是说我们域名相同、端口相同、协议相同才不算做是跨域,那么该怎么办。。。。。。。。。。
不用担心,自有跨域的解决办法、这里介绍两种,其他可google解决:
1.JsonP跨域解决:ajax中设定datatype的类型为jsonp就行了,很简单;
优点是:对于一些古老的浏览器很高的支持;例如万恶的ie。。。
缺点是:只能发出GET请求,其他method无法操作,例如POST、DELETE等
2.cros同源策略:设置方式,只要在action中设置header头部即可,也是最简单、最常用的一种(如果不考虑ie的话)
优点:操作方便,只需添加header;支持新兴浏览器;所有方式都可采用:例如GET、POST、DELETE、PUT、PATCH、OPTIONS等
Access-Control-Allow-Origin:*或者建立信任的url,例如:Access-control-Origin:http://frontend.news.com;
Access-Control-Allow-Methods:*允许操作的方法为所有;
缺点:对ie的支持不好,兼容性IE10以前的都不能用。
The END
在yii2.0框架中集成了restful api的部分,封装在yii est下,我们要做的工作有:
1.apache或nginx中开启rewrite伪静态模式(可自行搜索)
2.新建api模块,专门用来存放api相关,并配置响应格式为json而不是xml;
3.改造请求错误提示为Json格式,而非html;
4.测试调试请求;
5.前端进行接收,这部分我们说下前端ajax如何跨域做出请求;
准备:
1.新建news表用来展示(也可以用命令行migration去建表):
DROP TABLE IF EXISTS `news`; CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `time` int(11) NOT NULL DEFAULT "0", PRIMARY KEY (`id`), UNIQUE KEY `title` (`title`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2.api的请求工具:chrome中建议安装postman、firefox中安装HttpRequest,其他浏览器自行解决;
3.Json的查看工具:chrome中建议安装JSONView,会显示格式化的json,firefox中安装jsonformater,其他浏览器自行解决;
3.开启伪静态rewrite、并且配置api的二级域名为api.news.com格式,绑定在api/web下面;
1.copy一份frontend或backend目录下的文件重命名为api放置在同级下作为api的内容,在common>bootstrap.php文件中依赖注入声明api模块:
Yii::setAlias("@api",dirname(dirname(__DIR__))."/api");
2.在api下新建v1、v2作为我们不同版本的内容、并在里面新建controllers、models、views部分,并分别在v1、v2下新建Module.php声明命名空间;
<?php
/**
* @see https://github.com/craftsmann.
* @author craftsmann <m13993334619@163.com>
*/
namespace apimodulesv1;
class Module extends yiiaseModule
{
public $controllerNamespace = "apimodulesv1controllers";
public function init()
{
parent::init(); // TODO: Change the autogenerated stub
}
}
?>
3.api文件夹相关命名空间可自行修改,这里我们要对配置文件作出修改:
<?php
$params = array_merge(
require(__DIR__ . "/../../common/config/params.php"),
require(__DIR__ . "/../../common/config/params-local.php"),
require(__DIR__ . "/params.php"),
require(__DIR__ . "/params-local.php")
);
return [
"id" => "app-api",
"basePath" => dirname(__DIR__),
"bootstrap" => ["log"],
"language" =>"zh-CN",
"controllerNamespace" => "apicontrollers",
"modules"=>[
"v1"=>["class"=>"apimodulesv1Module"],
"v2"=>["class"=>"apimodulesv2Module"],
],
"components" => [
"user" => [
"identityClass" => "commonmodelsUser",
"enableAutoLogin" => false,
"enableSession" =>false,
"loginUrl" =>null,
],
"log" => [
"traceLevel" => YII_DEBUG ? 3 : 0,
"targets" => [
[
"class" => "yiilogFileTarget",
"levels" => ["error", "warning"],
],
],
],
"errorHandler" => [
"errorAction" => "site/error",
],
"urlManager" => [
"enablePrettyUrl" => true,
"enableStrictParsing" => true, // 是否执行严格的url解析
"showScriptName" => false,
"rules" => [
[
"class"=>"yii
estUrlRule",
"controller"=>["v1/users","v1/news"],
]
],
],
],
"params" => $params,
];
?>
4.新建api>modules>v1>controllers>NewsController控制器用来响应,并重写behaviors响应为json:
<?php
/**
* @see https://github.com/craftsmann.
* @author craftsmann <m13993334619@163.com>
*/
namespace apimodulesv1controllers;
use yii
estActiveController;
class NewsController extends ActiveController
{
//响应数据为
public $modelClass="apimodulesv1modelsGoods";
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors["contentNegotiator"]["formats"] = ["application/json" => yiiwebResponse::FORMAT_JSON];
return $behaviors;
}
?>5.新建model在api>modules>v1>modles>News.php,可采用gii生成;
以上就是api模块建立的过程;
1.在common>controllers>ErrorAction.php去重写action错误的提示;
?php
/**
* @see https://github.com/craftsmann.
* @author craftsmann <m13993334619@163.com>
*/
namespace commoncontrollers;
use Yii;
use yiiaseException;
use yiiaseUserException;
use yiiwebHttpException;
class ErrorAction extends yiiwebErrorAction
{
public function run()
{
if (($exception = Yii::$app->getErrorHandler()->exception) === null) {
// action has been invoked not from error handler, but by direct route, so we display "404 Not Found"
$exception = new HttpException(404, Yii::t("yii", "Page not found."));
}
if ($exception instanceof HttpException) {
$code = $exception->statusCode;
} else {
$code = $exception->getCode();
}
if ($exception instanceof Exception) {
$name = $exception->getName();
} else {
$name = $this->defaultName ?: Yii::t("yii", "Error");
}
if ($exception instanceof UserException) {
$message = $exception->getMessage();
} else {
$message = $this->defaultMessage ?: Yii::t("yii", "An internal server error occurred.");
}
if (Yii::$app->getRequest()->getIsAjax()) {
echo json_encode(
[
"name"=>$name,
"msg" =>$message
]
);
} else {
echo json_encode(
[
"status"=>"error",
"code"=>$code,
"msg" =>$message,
]
);
}
}
}
这里我们做出错误请求,api.news.com/v3你会发现,提示Json数据为
{status: "error", code: 404, msg: "页面未找到。"}
这在api请求错误时很有帮助;
1.在数据表news中插入数据
2.在postman中我们输入http://api.news.com/v1/news会显示出news的数据;
3.格式:一般Restful Api的格式是固定的;当然也可以去重写;
GET http://api.news.com/v1/news 列出所有新闻
GET http://api.news.com/v1/news/1 列出id为1的新闻
POST http://api.news.com/v1/news 新建新闻
DELETE http://api.news.com/v1/news/1 删除id为1的新闻
PUT/PATCH http://api.news.com/v1/news/1 修改id为1的新闻
我们可以在postman中输入以上url做测试,其他方式例如OPTIONS、HEAD可寻找资料或查看手册;
以上我们就搭建完成了Restful api的接口;
前面:前端所有部分都通过jquery来做ajax请求;
事实上我们只需要一个button按钮来测试我们所得到的数据;
在frontend.news.com中新建一个action并render一个视图我们用来测试
<?php
/**
* @see https://github.com/craftsmann.
* @author craftsmann <m13993334619@163.com>
*/
use yiiootstrapActiveForm;
frontendassetsAppAsset::register($this);
?>
<?php $this->beginBlock("js")?>
$("#api").on("click",function(){
$.ajax({
type: "get",
url: "http://api.hotel.com/v1/news/1",
success: function(data){
$("#message").html("新增新闻名称:"+data.name);
},
error: function(news){
$("#message").html(news.responseJSON[0].message);
}
});
});
<?php $this->endBlock()?>
<?php $this->registerJs($this->blocks["js"],yiiwebView::POS_END);?>
<div class="container">
<div class="form-group">
<?= yiihelpersHtml::Button("提交",["class"=>"btn btn-default","id"=>"api"])?>
</div>
<a id="message"></a>
</div>
当你在frontend.news.com用ajax去请求我们api.news.com的api接口时候,你会发现:请求失败,并报错,原因是跨域,浏览器做出了限制;
也就是说我们域名相同、端口相同、协议相同才不算做是跨域,那么该怎么办。。。。。。。。。。
不用担心,自有跨域的解决办法、这里介绍两种,其他可google解决:
1.JsonP跨域解决:ajax中设定datatype的类型为jsonp就行了,很简单;
优点是:对于一些古老的浏览器很高的支持;例如万恶的ie。。。
缺点是:只能发出GET请求,其他method无法操作,例如POST、DELETE等
2.cros同源策略:设置方式,只要在action中设置header头部即可,也是最简单、最常用的一种(如果不考虑ie的话)
优点:操作方便,只需添加header;支持新兴浏览器;所有方式都可采用:例如GET、POST、DELETE、PUT、PATCH、OPTIONS等
Access-Control-Allow-Origin:*或者建立信任的url,例如:Access-control-Origin:http://frontend.news.com;
Access-Control-Allow-Methods:*允许操作的方法为所有;
缺点:对ie的支持不好,兼容性IE10以前的都不能用。
The END
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇: MYSQL 中SUM函数和关联查询
