如标题:我想在ajax的header头增加自定义Token进行跨域api认证并调用,api使用laravel5编写,如何实现?

首先,了解下CORS简单请求和复杂请求。

     -- CORS简单请求 --

链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

1、ajax跨域,使用CORS方式  --  (ajax跨域会自动提交origin字段,用户不可伪造)

2、HTML的js:

</body>
<script type="text/javascript">
$(function(){
$(document).on("click", ".btn-all2", function(){
$.ajax({
url:"http://t-local.*****.com/wechat/auth/up?call_back=http%3A%2F%2Ftest.*****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
dataType:"json",
type:"get", //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin // 允许携带cookie凭证
xhrFields: { withCredentials: true },
// 允许跨域
crossDomain: true, success:function(data){
console.log('success');
console.log(JSON.stringify(data));
},
error: function(data){
console.log('error');
console.log(JSON.stringify(data));
}
})
})
})
</script>
</html>

laravel5后台ajax请求过滤中间件: -- laravel 5 用来处理【简单请求】或者【复杂请求的第二次请求】

//跨域XML请求,会自动带上http_origin字段
public function handle( $request, Closure $next )
{
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = Config::get('app.allow_origin');
$allow_origin_dynamic = Config::get('app.allow_origin_dynamic'); $allowOrigin = false;
if ( in_array( $origin, $allow_origin ))
{
$allowOrigin = true;
} else {
foreach ( $allow_origin_dynamic as $item )
{
if ( strpos( $origin, $item ) !== false )
{
$allowOrigin = true;
break;
}
}
}
if ( $allowOrigin )
{
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
header('Access-Control-Allow-Credentials:true');
}
return $next($request); }

    ------  CORS复杂请求   --------

链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

复杂请求 =【预请求 + 简单请求】;

一次XMLHttpRequest会发送两次请求,一次options、一次自定义的请求

那么在TP5中,我们可以使用行为扩展处理ajax|axios 带自定义头token的CORS请求,在laravel5中怎样解决呢?

laravel5 解决方案:

1、域名一:local.domian.com前端发起跨域ajax请求:访问laravel5的t-local.domian.com域名二

<script type="text/javascript">
$(function(){
$(document).on("click", ".btn-all2", function(){
$.ajax({
url:"http://t-local.****.com/api/wechat/auth/up?call_back=http%3A%2F%2Ftest.****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
dataType:"json",
type:"get", //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin //自定义请求头认证token
headers: { 'token' : "2211zxz" }, // 允许携带cookie凭证
xhrFields: { withCredentials: true },
// 允许跨域
crossDomain: true, success:function(data){
console.log('success');
console.log(JSON.stringify(data));
},
error: function(data){
console.log('error');
console.log(JSON.stringify(data));
}
})
})
})
</script>

2、在laravel的route/api.php路由文件,增加以下路由规则:

/**
* laravel5发送复杂cors请求,类似jwt、自定义请求头token等,会先发送预请求options
* @param : 预请求options的【Access-Control-Allow-Origin:】绝对不可以设置成*,否则报错
* @return : code 200
* date: 2019年10月30日下午2:29:50
* author: xzz
*/
Route::options('/{all}',function () {
//file_put_contents(storage_path('logs/SERVER_Header.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
//file_put_contents(storage_path('logs/SERVER_Header.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND);
$origin = request()->header('ORIGIN')??request()->header('HTTP_ORIGIN'); header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Origin, Access-Control-Request-Headers, SERVER_NAME, Access-Control-Allow-Headers, cache-control, token, X-Requested-With, Content-Type, Accept, Connection, User-Agent');
})->where(['all' => '([a-zA-Z0-9-]|/)*']);

3、返回前端F12打开,发现options请求已通过:

4、在创建一个【ajax简单请求】验证中间件(如果是简单请求,上面都可以省略),App\Middleware\AjaxHeader.php,kernel.php注册在api里面

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\{Config}; class AjaxHeader
{
/**
* @param $request
* @param Closure $next
* @return mixed
*/
public function handle( $request, Closure $next )
{
file_put_contents(storage_path('logs/1.txt'), var_export($_SERVER, true) . PHP_EOL, FILE_APPEND);
file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND); $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = Config::get('app.allow_origin');
$allow_origin_dynamic = Config::get('app.allow_origin_dynamic'); $allowOrigin = false;
if ( in_array( $origin, $allow_origin ))
{
$allowOrigin = true;
} else {
foreach ( $allow_origin_dynamic as $item )
{
if ( strpos( $origin, $item ) !== false )
{
$allowOrigin = true;
break;
}
}
}
if ( $allowOrigin )
{
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
header('Access-Control-Allow-Headers:x-requested-with,content-type,token');
header('Access-Control-Allow-Credentials:true');
}
return $next($request);
/* return $next($request)-> header('Access-Control-Allow-Origin', '*')
-> header('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE')
-> header('Access-Control-Allow-Headers', 'Content-Type,Accept,Authorization,X-Requested-With');*/
}
}

5、上面注册的api中间件绑定到t-local的api/wechat/xxx路由上,从local域名发起访问t-local域名,发现get请求也成功返回了json数据

返回的json数据:数据正确返回了,至于返回的是什么,这已经不重要了,不是吗?!!

6、至此,则完成了laravel5 处理ajax 携带自定义header头Token,并发起的跨域CORS的复杂请求。

原创:【ajax | axios跨域简单请求+复杂请求】自定义header头Token请求Laravel5后台【亲测可用】的更多相关文章

  1. dropwizard使用cors支持跨域浏览器取不到自定义header问题

    dropwizard支持cors的配置如下: public void run(Configuration conf, Environment environment) { // Enable CORS ...

  2. 汉字转整数,比系统简单易用!a2iLxx (覆盖物 16十六进制,VC6亲测可用)请提供意见~

    #include "string.h" #define INVALID_VALUE_LXX ((1 << (8 * sizeof(int) -1)) - 1) /*有符 ...

  3. 使用ajax请求接口,跨域后cookie无法设置,全局配置ajax;及使用axios跨域后cookie无法设置,全局配置axios

    问题一: 使用ajax/axios跨域请求接口,后端放行了,能够正常获取数据,但是cookie设置不进去,后端登录session判断失效 ajax解决办法: //设置ajax属性 crossDomai ...

  4. $Django 前后端之 跨域问题(同源策略) vue项目(axios跨域请求数据)

    1 跨域问题(多个域之间的数据访问) #同源策略(ip port 协议全部相同) #本站的只能请求本站域名的数据 #CORS实现(跨域资源共享) #实现CORS通信的关键是服务器.只要服务器实现了CO ...

  5. 原生JS实现Ajax及Ajax的跨域请求

      前  言          如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...

  6. Ajax之跨域请求

    一.引子 我现在开启了两个django项目,分别叫Demo1和Demo2,Demo1中有一个路径‘http://127.0.0.1:8000/index/’,对应的视图是index视图返回一个inde ...

  7. 【转载】Ajax JS 跨域请求

    原文: 简单的ajax请求:http://blog.csdn.net/net_lover/article/details/5172509 复杂的ajax请求:http://blog.csdn.net/ ...

  8. leyou_03_cors解决ajax的跨域请求问题

    1.为什么会有跨域问题 因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是与当前页域名相同的路径,这能有效的阻止跨站攻击. 因此:跨域问题 是针对ajax的一种限制 ...

  9. jQuery的ajax jsonp跨域请求

    了解:ajax.json.jsonp.“跨域”的关系 要弄清楚以上ajax.json.jsonp概念的关系,我觉得弄清楚ajax是“干什么的”,“怎么实现的”,“有什么问题”,“如果解决存在的问题”等 ...

随机推荐

  1. 补充1:IDA的脚本IDC语言

    1.IDA脚本的打开与使用: IDA脚本两种语言:IDC(IDC,本地脚本语言)和Python 2.IDC语言介绍 1.IDC变量:IDC是一种松散的语言,没有明确的类型.使用3中数据类型,整数(ID ...

  2. Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量

    在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...

  3. 复盘一篇讲sklearn库的文章(下)

    skleran-处理流程 获取数据 以用sklearn的内置数据集, 先导入datasets模块. 最经典的iris数据集作为例子. from sklearn import datasets iris ...

  4. cad 画图面板的尺寸大小定义

    输入limits 输入左下角点为 0,0 输入右上角点为大家需要的数  这里为100,50 输入zoom 输入a 就可以实现自定义编辑 注意事项 如果在你已经操作过的图纸上可能会失效 重新建一张图纸就 ...

  5. Kotlin匿名函数与闭包详解

    Lambda表达式实例演练: 继续先来编写一些Lambda表达式相关的代码: 接下来想从上面的字符串数组中找到带有"h"的字符串并打印出来: 如果学习了Java8的Lambda表达 ...

  6. 微服务学习之路(三)——实现RPC远程服务调用

    RPC(Remote Producedure Call)调用原理:服务消费者称为客户端,服务提供者称为服务端,处于不同网络地址,需要建立网络连接.建立连接后,双方还必须按照某种约定的协议进行网络通讯— ...

  7. Windows GUI自动化测试技术的比较和展望

    https://www.cnblogs.com/yufun/archive/2009/10/10/1580132.html [这里的自动化测试专指GUI自动化(不包含Web)] 以前写过一篇跟UI自动 ...

  8. (4)给树莓派安装中文输入法Fcitx及Google拼音输入法

    sudo apt-get install fcitx fcitx-googlepinyin fcitx-module-cloudpinyin fcitx-sunpinyin 安装完毕,重启即可.

  9. MongoDB远程连接-MongoDB Compass

    MongoDB Compass Community连接界面设置

  10. Numpy | 08 切片和索引

    ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样. (1)ndarray 数组索引可以基于 0 - n 的下标进行: (2)切片对象可以通过内置的 ...