APP下载

Ajax跨域访问问题的分析与解决

2020-02-01常艳

电子技术与软件工程 2020年10期
关键词:跨域开发技术服务器端

常艳

(晋城技师学院 山西省晋城市 048000)

随着计算机网络的发展与普及,网站设计与开发是现在非常热门的一个行业。前后端分离开发方式已成为网站开发的主流开发方式。前后端代码分离导致了Ajax 请求时的跨域访问问题,本文就Ajax 访问机制、Ajax 跨域访问问题产生的原因以及解决方案进行了深入的分析与研究。

1 Ajax访问机制

在传统的web 开发技术中,加载或者刷新数据需要重新请求页面,会造成网页进行重新加载,从而刷新整个页面。Ajax(Asynchronous JavaScript & XML)是一种新的web 开发技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的数据进行更新,使得用户体验更好。

Ajax 的请求步骤如下:

(1)创建XMLHttpRequest 对象,也就是创建一个异步调用对象;

(2)创建一个新的HTTP 请求,并指定该HTTP 请求的方式、URL 及验证信息;

(3)设置响应HTTP 请求状态变化的函数;

(4)发送HTTP 请求;

(5)获取异步调用返回的数据;

(6)使用JavaScript 和DOM 实现局部刷新。

2 前后端分离开发技术

现在前后端分离开发技术已成为网站开发的主流发展方向。前后端分离开发即网站开发前台代码(HTML 和JavaScript)和后台代码(本文中采用PHP)独立开发,前后端代码可放在同一个服务器上,也可分布于不同的服务器上。后端代码负责提供数据接口(以下简称API)用于完成数据处理和交互,前台使用Ajax 技术请求后台API,来实现网站功能、以及数据交互。前后端分离开发技术可以使得前后端代码同时开发,提高开发效率,同时易于排错,扩展性好。

3 Ajax跨域访问问题产生的原因

3.1 域名不一致

前端页面的域名和页面中访问的API 的域名不一致,导致页面无法正常使用API。例如,开发初期前端页面多在本机PC 上进行开发和测试,那么访问前端页面的URL 为http://localhost/ems/yjglxt/login.html,那么前端域名为localhost,后台接口部署于服务器上,API 访问URL 为http://39.106.33.124/ems/public/index.php/login,那么API 的域名为39.106.33.124,前端和后端域名不一致,导致Ajax 访问时发生跨域访问问题,不能正常访问API 接口。

3.2 端口不一致

前后端代码位于同一台服务器或PC,域名一致,但是访问端口不一致,导致Ajax 跨域访问问题,无法正常访问接口。例如访问前端页面的URL 为http:// 39.106.33.124/ems/yjglxt/login.html,那么前端域名是39.106.33.124,端口默认为80。访问API 的URL 为http://39.106.33.124:8080/ems/public/index.php/login,那么后端域名为39.106.33.124,端口为8080,前后端域名一致,但是端口不一致,同样会导致Ajax 跨域访问问题,不能正常访问API 接口。

4 Ajax跨域访问带来的问题

4.1 报错

如果前后端域名不一致或前后端访问端口不一致,在页面中使用Ajax 访问后台API 接口会报错,例如前端访问域名是127.0.0.1,后端API 访问域名是localhost,则会报错,错误信息如下所示:

Access to XMLHttpRequest at 'http://localhost/ems/public/index.php/login' from origin 'http://127.0.0.1' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

4.2 无状态访问

4.2.1 浏览器访问机制

HTTP 是一种无状态的通信协议,它允许将超文本标记语言(HTML)文档从Web 服务器传送到客户端浏览器(以下简称客户端)。HTTP 协议是无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。

会话指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(session)是web 程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是cookie 与session。cookie通过在客户端记录信息确定身份,session 通过在服务器端记录信息确定用户身份。

通常情况下,客户端每次请求服务器时,都会形成一次会话,即创建一个session,服务器端会生成一个sessionId,用来唯一标识一次会话。服务器会把一些登录信息保存在session 中,同时会把sessionId 传给客户端,客户端会把sessionId 存储在cookie 中。客户端下次再请求服务器时,会把cookie 信息传送到服务器,这样服务器会自动获取到客户端cookie 中的sessionId,根据sessionId 去查询服务器端session 中是否保存有客户端的登录信息,如果查询到登录信息,说明客户端已登录;如果查询不到登录信息,说明客户端未登录。

4.2.2 Ajax 跨域访问导致session 失效

cookie 不可跨域名访问,客户端在进行ajax 跨域访问时不会把cookie 值带过去,就会造成服务器获取不到客户端cookie 中的sessionId,因此服务器在每次跨域访问时自动创建一个新的sessionId,这样也等于是开始一次新的会话,导致服务器端无法记住客户端的登录状态。

Ajax 跨域访问后端API 时,会导致每次请求时,服务器都会在客户端的cookie 里设置一个新的sessionId,会将原有的sessionId覆盖,这样会导致客户端每一次请求服务器都相当于是开始一个新的会话,客户端无法记住自己的登录状态,也就是客户端对于服务器来说始终处于未登录状态。

5 Ajax跨域访问问题解决方案

5.1 配置后台PHP的API接口允许跨域访问,方法如下面代码所示

header(“Access-Control-Allow-Origin:*”),表示该API 接口允许所有网站进行跨域访问,这种方法操作简单,但是安全性不高。

这种方法可以使得Ajax 可以正常访问后台API 接口,但是无法解决sessionId 丢失或sessionId 改变的问题,服务器仍然没有办法记住客户端的登录状态。

5.2 允许客户端Ajax跨域访问时,把Cookie带到服务器

在后台数据接口进行修改,加上下面的代码:

5.3 使用其他方式存储客户端的登录数据

5.3.1 使用数据库存储客户端登录数据

Ajax 跨域访问后端API 接口,如果登录成功,服务器端把本次会话的sessionId,以及相关的用户登录信息,保存到数据库中。同时编写代码把sessionId 传送给客户端,客户端使用JS 代码把sessionId 保存到COOKIE 中。

此后客户端每次进行Ajax 跨域访问其他接口时,把sessionId放在header 中发送到服务器,服务器从客户端的header 中获取到sessionId 后,根据sessionId 去数据库查询对应的登录信息,若查询到登录信息,则说明客户端已登录;若查询不到登录信息,则说明客户端处于未登录状态。

5.3.2 使用Redis 存储客户端登录数据

使用数据库存储客户端登录信息的一个弊端是,每次Ajax 跨域访问后端API 时,都要读/写数据库,在服务器并发访问数量较多的情况下,会造成服务器性能下降,用户等待时间变长,用户体验较差,甚至导致服务器崩溃,这种情况下使用数据库存储客户端登录数据变得不可取。

在服务器并发访问量较大的情况下,可以使用Redis 来存储客户端登录数据。Redis(Remote Dictionary Server),即远程字典服务,是一个开源的使用ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的API。Redis 数据库中所有数据都存储在内存中,由于内存的读写速度远快于硬盘和普通数据库,因此把客户端登录数据存储在Redis 中,会使得服务器具有很好的并发性,极大的提升服务器的访问速度和性能。

6 结束语

网站前后端代码分离的开发方法是现阶段主流的网站开发技术,是程序设计与开发的发展方向,但是会导致Ajax 跨域访问问题的发生,使得在网站开发中产生了许多的问题和困难。深入了解浏览器的访问机制,服务器和客户端的交互过程,session 会话的发生机制,以及深入学习Ajax 跨域访问的原因和解决方案,会在以后的网站开发过程中,避免许多可避免错误的发生,起到事半功倍的作用。

猜你喜欢

跨域开发技术服务器端
跨域异构体系对抗联合仿真试验平台
基于多标签协同学习的跨域行人重识别
为群众办实事,崂山区打出“跨域通办”组合拳
Linux环境下基于Socket的数据传输软件设计
浅析异步通信层的架构在ASP.NET 程序中的应用
计算机应用软件开发技术的几点探讨
防散脱纬编无痕弹力面料开发技术国际领先
基于Qt的安全即时通讯软件服务器端设计
中国煤层气开发技术的现状与未来
复杂产品设计知识应用开发技术研究