You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5 Material按钮点击生成Token时触发无效数组长度错误

问题:Angular 5结合PHP实现JWT时触发"Invalid array length"错误

我正在尝试用Angular 5搭配PHP实现JWT Token生成功能,测试阶段用CryptoAESJs库加密userid变量后通过POST请求发送到PHP脚本,但点击按钮触发方法时控制台抛出了数组长度无效的错误。

我的代码实现

Angular组件代码(app.component.ts)

// Imports
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import * as crypto from 'crypto-js';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(private http: HttpClient) {}

  ngOnInit() {}

  getToken() { 
    let userid = 123; 
    let key = "coded"; 
    let encUserID = crypto.AES.encrypt(userid, key); 
    const headerOptions = new HttpHeaders().set ('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 
    const params = new HttpParams().set('userID', encUserID); 
    this.http.post('http://aff.local/jwtTest.php', params, { headers: headerOptions, responseType: 'json' }).subscribe( 
      res=>{ console.log(res); }, 
      error=>{ console.log(error); } 
    ) 
  }
}

Angular模板代码(app.component.html)

<button mat-raised-button (click)='getToken()'>Click Me</button>

PHP脚本(jwtTest.php)

<?php 
header('Access-Control-Allow-Origin: *'); 
header('Content-Type: application/JSON'); 
header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS'); 
header('Access-Control-Allow-Headers: *'); 
error_reporting(E_ALL); 
require_once "CryptoJSAES.php"; 
require_once('JWT.php'); 
ini_set('log_errors', 0); 
ini_set('display_errors', 1); 

$key = "coded"; 
$id = $_POST['userID']; 
$token = CryptoJSAES::decrypt($id,$key); 
$jwt = JWT::encode($token, $key); 
$jwtDecode = JWT::decode($jwt, $key, array('HS256')); 
echo json_encode($jwtDecode); 
?>

错误信息

点击按钮后控制台抛出:

ERROR RangeError: Invalid array length
at WordArray.init.clamp (core.js:272)
at WordArray.init.concat (core.js:237)
at Object.pad (cipher-core.js:415)
at Object._doFinalize (cipher-core.js:492)
at Object.finalize (cipher-core.js:163)
at Object.encrypt (cipher-core.js:675)
at Object.encrypt (cipher-core.js:833)
at Object.encrypt (cipher-core.js:201)
at AppComponent.push../src/app/app.component.ts.AppComponent.getToken (app.component.ts:20)
at Object.eval [as handleEvent] (AppComponent.html:1)

我想知道这个错误是Material组件、浏览器的问题,还是Angular与PHP之间的传值问题?


问题根源分析

先给你明确结论:这个错误和Material组件、浏览器完全无关,错误堆栈已经把问题指向了crypto-js的加密逻辑——具体是在WordArray的clamp方法里触发了数组长度无效的异常,核心问题出在你调用加密方法的姿势上。

仔细看你代码里的crypto.AES.encrypt(userid, key):你直接传入了数字类型的123,但crypto-js的AES.encrypt方法要求第一个参数必须是字符串或者WordArray对象。当你传入数字时,内部处理会出现类型不兼容的问题,进而导致后续数组操作抛出长度无效的错误。

另外还有个隐藏坑:crypto.AES.encrypt返回的是一个CipherParams对象,不是直接的加密字符串,你直接把这个对象传给HttpParams.set,Angular在序列化参数时会把它转成[object Object],PHP端接收后肯定无法解密,这也是后续会踩的雷。

解决方案

修改你的Angular代码中的getToken方法,做两处关键调整:

  1. 将数字类型的userid转为字符串后再加密;
  2. 调用encUserID.toString()获取加密后的字符串,而不是直接传递CipherParams对象:
getToken() { 
  let userid = 123; 
  let key = "coded"; 
  // 把数字转为字符串,同时获取加密后的字符串
  let encUserID = crypto.AES.encrypt(userid.toString(), key).toString(); 
  const headerOptions = new HttpHeaders().set ('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 
  const params = new HttpParams().set('userID', encUserID); 
  this.http.post('http://aff.local/jwtTest.php', params, { headers: headerOptions, responseType: 'json' }).subscribe( 
    res=>{ console.log(res); }, 
    error=>{ console.log(error); } 
  ) 
}

额外验证点

另外建议你检查PHP端的CryptoJSAES.php是否和crypto-js的加密逻辑完全兼容——比如加密模式、填充方式(默认crypto-js用的是CBC模式、PKCS7填充),如果后续解密还是有问题,需要确保两端的加密配置完全匹配。

内容的提问来源于stack exchange,提问作者alim1990

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:00