AXIOS 跨域连接tms sparkel xdata服务器

XData 服务和sparkel 服务分别为tms bs中的组件,本人一直在使用。

使用vue axios组件一直无法连接两个服务器,无奈后台已经长期使用这两个服务器了,只能axios来配合解决,笔者在使用过程中遇到了以下的问题:

1:  axios 如何跨域访问sparkel服务器。

2:  axios 如何跨域访问xdata服务器。

3:  vue.js 数据需要Json嵌套需要转义功能。

 

涉及服务器的组件分别为SparkleStaticServer,XDataServer

问题需要一个个解决,

问题1解决:

  1):  需要修改Sparkel源码,sparkles源码中Sparkle.Module.Static.pas文件中下图类中

 

 

 

添加如下的几行即可

      C.Response.Headers.AddValue('Access-Control-Allow-Origin','*');
      C.Response.Headers.AddValue('Access-Control-Allow-Methods','GET,PUT,POST,DELETE,OPTIONS');
      C.Response.Headers.AddValue('Access-Control-Allow-Headers','content-type');
      C.Response.Headers.SetValue('access-control-max-age', '1728000');

  

   2):  vue.js中axios的测试代码如下

<script>
    const ts_url = 'http://192.168.1123:20089';


    new Vue({
        el: "#app",
        data: {
            title: 'ts_title'
        },
        created() {
            axios.defaults.baseURL = ts_url ;
            axios.get('/static/1.json')
                 .then(res => {
                     console.log(res.data)
                 })
                 .catch(err => {
                     console.error(err);
                 });
        },
    })
</script>

  

  问题1完美解决。

问题2的解决:

  1):  看了XData的源码,发现本身源码具有CROS的代码,只是调试了几次折腾了3个小时发现依然达不到我要的效果,不知道怎么用的,还是修改源码来得快一些,修改XData中源码XData.Module.Base.pas中如下图

 

 

   2):  使用axios的代码进行调试

  

<script>
    const ts_url = 'http://192.168.1123:20089';


    new Vue({
        el: "#app",
        data: {
            title: 'ts_title'
        },
        created() {
            axios.defaults.baseURL = ts_url ;
            var jsons = {},
                 qjson_data = {};


            qjson_data['Permiss'] = 'Admin;XPlay';
            qjson_data['Fun'] = 'GetPermissListSign';

            q_str = JSON.stringify(qjson_data);
            jsons['QJson'] = qjson_data; //Json转义
            axios.post('/Server/Manage/AppManageClassFun', jsons, {
                    headers: {
                         'Authorization': 'Basic VEhJTktTSUdOOjIwMTUxMTEz'
                     }
                 })
                 .then(res => {
                     console.log(res.data)
                 })
                 .catch(err => {
                     console.error(err);
                 });
        },
    })
</script>

    结果发现不管我怎么调试,出现的现象都是获取不到文件,然而我直接在浏览器中使用链接确实可以的,一直找不到问题所在,网络找了3小时,没有结果,经过一天思考各方面测试后才发现原来是我增加,http中增加了Authorization,浏览器默认先发送了OPTIONS的包,主要原因是为了服务器的安全,详细见下面网址,

https://segmentfault.com/q/1010000010159122?sort=created
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

  无奈,查了下数据发现XDATA在客户端发送OPTIONS的时候提示客户端需要验证,可是尝试修改AXIOS增加HEAD到OPTIONS中去,没有找到任何方法增加,看来还是改服务器吧,然后服务器还是ProcessRequest方法,修改如下,当发送OPTINS包的时候去掉验证好了。

 
procedure TXDataBaseModule.ProcessRequest(const C: THttpServerContext);
var
  Context: TXDataBaseRequestHandler;
begin
  if C.Request.Method<>'OPTIONS' then
  begin
    if (UserName <> '') and (Password <> '') then
    begin
      if not FBasicAuthentication.Authenticate(C) then
      begin
        C.Response.StatusCode := 401;
        C.Response.Headers.SetValue('www-authenticate', 'Basic');
        Exit;
      end;
    end;
  end;

  Context := CreateBaseHandler(C);
  try
    Context.ProcessRequest;
  finally
    Context.Free;
  end;
end;

  在使用AXIOS进行测试,发现验证可以过了,请求的数据异常。查了下XData发现原来是前端过来的JSON 数据嵌套的问题,正常XData接收的第二层JSON数据必须要有转义符'\'。

问题3解决

  1:  尝试各种JS中各种JSON方法,均无果,去百度搜索,完全文不对题。难道是想让我进行字符串替换吗?

  2:  还是静下心来看书吧,看了半天书,终于知道只要两次序列化就可以,哎! 

 

<script>
    const ts_url = 'http://192.168.1123:20089';


    new Vue({
        el: "#app",
        data: {
            title: 'ts_title'
        },
        created() {
            axios.defaults.baseURL = ts_url ;
            var jsons = {},
                qjson_data = {};

            qjson_data['Permiss'] = 'test;zhao;Permi';
            qjson_data['Fun'] = 'GetPermissListSign';

            jsons['QJson'] = JSON.stringify(qjson_data); //Json转义
            axios.post('/Server/Manage/AppManageClassFun', JSON.stringify(jsons), {
                    headers: {
                        'Authorization': 'Basic VEhJTktTSUdOOjIwMTUxMTEz',
                        'Content-Type': 'application/json'
                    }
                })
                .then(res => {
                    console.log(res.data)
                })
                .catch(err => {
                    console.error(err);
                });
        },
    })
</script>

  大功告成

 

posted @ 2020-03-12 11:09  _成飞  阅读(457)  评论(0编辑  收藏  举报