如何使用 Typescript 进行 AJAX 请求? (使用 JSON)

Posted

技术标签:

【中文标题】如何使用 Typescript 进行 AJAX 请求? (使用 JSON)【英文标题】:How can I do an AJAX request with Typescript? (using JSON) 【发布时间】:2017-09-29 03:53:41 【问题描述】:

我正在学习 AJAX,我正在尝试使用参数执行 AJAX 请求,但在发送 JSON 数据时遇到问题:

我正在使用 Typescript 和 php(使用 Codeigniter),其想法是创建一个 Typescript 对象并将其以 JSON 格式发送到 PHP。所以基本上我创建了一个对象并使用我在 Google 上找到的 stringify 方法将此对象转换为 JSON(或者我应该说的 JSON 形式的字符串?)并使用 AJAX 将其发送到服务器,但数据没有到达正确。

我使用print_r($_POST); 来查看服务器正在接收什么,它向我显示以下内容:

Array
(
    ["_dificultad_seleccionada":"Normal"] => 
    [0] => 
)

我从 stringify 获得的整个字符串显示为键,值为空。

我不太明白发生了什么,不是将对象转换为 JSON 并将其发送到服务器的方式进行字符串化吗?为什么它没有正确发送对象?

客户端代码:

Dificultad.ts(我要发送到服务器的类)

class Dificultad 

    private _dificultad_seleccionada: string;

    constructor (dificultad_seleccionada: string) 
        this._dificultad_seleccionada = dificultad_seleccionada;
    

    get dificultad_seleccionada(): string 
        return this._dificultad_seleccionada;
    

    set dificultad_seleccionada(dificultad_seleccionada: string) 
        this._dificultad_seleccionada = dificultad_seleccionada;
    


Lib.ts(我在这里声明所有 const、DOM 元素等)

const BASE_URL: string = window.location.origin + "/Project_name/";
type CallbackFunction = (arg: any, ...args: any[]) => void;

Main.ts(这里是我发送 AJAX 的地方)

    $(document).ready(function() 

        $( "a#boton_seleccion_dificultad" ).click(function(event) 

            event.preventDefault();

            if (pasapalabra.gameState == GameState.GAME_STARTING) 

                let _dificultad: Dificultad = new Dificultad("Normal");
                sendAjaxRequest("POST", "get_dificultad_seleccionada", JSON.stringify(_dificultad), function(response) 
                    console.log(response);
                );

            

        );

    );

function sendAjaxRequest(_type: string, _url: string, _params: string, _callback: CallbackFunction) 

    var request = $.ajax(
        type: _type,
        url: BASE_URL + _url,
        data: _params,
        contentType: 'json'
    );
    request.done(function(res) 
        _callback(res);
    );
    request.fail(function(jqXHR, textStatus) 
        console.error(jqXHR)
        _callback( err: true, message: "Request failed: " + textStatus );
    );


服务器代码:

Welcome.php

class Welcome extends CI_Controller 

    public function __construct() 
    parent::__construct();
        $this->load->database();
        $this->load->library("grocery_CRUD");
        date_default_timezone_set('Europe/Madrid');
        $this->load->library('session');
        $this->load->helper('url');
        $this->load->model("Rol_model");
        $this->load->model("Questions_model");
    

public function get_dificultad_seleccionada() 

        print_r($_REQUEST); print_r($_POST);
        //echo json_encode($dificultad);
    


我在客户端使用 stringify 进行的对象转换似乎存在问题,因为如果我像这样更改 ajax 调用,手动发送 JSON,它可以工作:

Main.ts

sendAjaxRequest("POST", "get_dificultad_seleccionada", "_dificultad_seleccionada":"Normal", function(response) 
                console.log(response);
            );

似乎我做错了什么,但我不知道可能是什么,如何以 JSON 格式将此对象发送到服务器?

我想为我的程序中的所有AJAX请求做一个通用函数,但是我不太清楚我是否正确地做,回调函数的类型可以吗?还是我错了?

非常感谢您的帮助。

【问题讨论】:

所以...您将一个不是参数的字符串传递给您的参数,并且很困惑为什么将所述字符串视为参数?你没有告诉你的服务器你给它json。使用 get 请求发送 json 也不是很常见。并非闻所未闻,只是不常见。 我是 AJAX 新手,我不完全理解它是如何工作的,但是 JSON.stringify(_dificultad) 基本上是一个带有这个 "_dificultad_seleccionada":"Normal" 的字符串,所以它应该是相同的数据,我不明白为什么它不适用于相同的数据。我传递的不是参数是什么意思?我应该通过 POST 请求发送它吗? 使用 dataType:'json' AJAX 请求失败... dataType 指定您期望服务器返回的内容,这有点不同。 contentType 会更合适。但是...如果您要发送 json 字符串,我仍然建议使用 POST 而不是 GET。另请注意,在 php 中,它不会在 GET 或 POST 中,而是在其他地方(google how to get json data from request in php) 它不适用于 stringify,因为 jquery 不会将 json 转换为参数字符串,它保持原样。然后服务器假定它是一个参数字符串并对其进行解析,为您留下一个包含没有值的 json 字符串的键。 【参考方案1】:

我想我已经解决了这个问题,我正在发送与以前相同的数据,但现在我使用 contentType: 'json' 告诉服务器我正在发送 JSON 并在服务器端 (PHP) 我使用以下获取 json:json_decode(file_get_contents('php://input'), true);

Main.ts

$(document).ready(function() 

    $( "a#boton_seleccion_dificultad" ).click(function(event) 

        event.preventDefault();

        if (pasapalabra.gameState == GameState.GAME_STARTING) 

            let _dificultad: Dificultad = new Dificultad("Normal");

            sendAjaxRequest("POST", "get_dificultad_seleccionada", JSON.stringify(_dificultad), function(response) 
                console.log(response);
            );

        

    );
);

function sendAjaxRequest(_type: string, _url: string, _params: string, _callback: CallbackFunction) 

    var request = $.ajax(
        type: _type,
        url: BASE_URL + _url,
        data: _params,
        contentType: 'json'
    );
    request.done(function(res) 
        _callback(res);
    );
    request.fail(function(jqXHR, textStatus) 
        console.error(jqXHR);
        _callback( err: true, message: "Request failed: " + textStatus );
    );


Welcome.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller 

    public function __construct() 
    parent::__construct();
        $this->load->database();
        $this->load->library("grocery_CRUD");
        date_default_timezone_set('Europe/Madrid');
        $this->load->library('session');
        $this->load->helper('url');
        $this->load->model("Rol_model");
        $this->load->model("Questions_model");
    

public function get_dificultad_seleccionada() 

        $data = json_decode(file_get_contents('php://input'), true);
        print_r($data);
        echo $data["_dificultad_seleccionada"];
    


现在服务器正确地获取了值,我想现在它正在以 JSON 格式获取它。

【讨论】:

好吧..我的意思是......在这个答案中你根本没有发送json。只是要清楚。您可以删除 JSON.parse(JSON.stringify 并获得相同的结果。 没错,没有它它仍然可以工作......那么为什么使用 stringify 不起作用?我现在正在使用 POST 并且我写了 contentType: 'json',但它仍然无法正常工作,现在 $_POST 或 $_REQUEST 都没有任何东西,它们都返回:Array ( )

以上是关于如何使用 Typescript 进行 AJAX 请求? (使用 JSON)的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 VSCode 使用本地安装的 TypeScript

typescript 如何使用服务,请参阅评论。

TypeScript 回调没有在其签名中完全实例化类

当发送的请求是 Ajax 请求时,如何从 ManagedBean 重定向?

我可以创建一个 TypeScript 类型并在 AJAX 返回 JSON 数据时使用它吗?

如果站点使用 Ajax,如何检查 Selenium WebDriver?