CORS POST请求在授权标头上抛出

CORS POST request throws on Authorization header

本文关键字:权标 授权 POST 请求 CORS      更新时间:2023-09-26

我试图发送一个CORS POST请求到我的API,它抛出TypeError每次我使用'授权'头。请求甚至没有被发送,因此服务器没有参与其中。但这只发生在我的测试中。当我在Chrome中尝试它时,它工作得很好。

下面是我要测试的函数:

export const postNewEmployee = formData => {
  return fetch('http://localhost:3003', {
                             method: 'POST',
                             headers: {
                               'Authorization': 'Bearer test123',
                               'Content-Type': 'application/json'
                             },
                             body: JSON.stringify(formData)
                           })
                           .then(response => response)
                           .catch(error => {
                             throw error;
                           });
  };

及其测试:

import * as API from './api';
describe('postNewEmployee', () => {
  it('posts the form data asynchronously', () => {
    let formData = {
      employee: {
        name: 'Test Person',
        email: 'test@person.nu',
        address: 'an adress 123'
      }
    };
    return API.postNewEmployee(formData)
      .then(json => {
        expect(json.status).toEqual(201);
      }).catch(error => {
        console.log(error);
      });
  });
});

这个应用程序是一个用create-react-app创建的react/redux应用程序,所以我使用Jest和JSDOM来测试它。问题是,如果我在fetch()调用中注释掉Authorization头,它就能正常工作。但是如果我加上这个标题,我得到这个:

TypeError: Cannot convert undefined or null to object
    at Object.getRequestHeader (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:20:23)
    at setDispatchProgressEvents (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:909:38)
    at XMLHttpRequest.send (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:700:11)
    at /Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:429:11
    at Object.<anonymous>.self.fetch (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/whatwg-fetch/fetch.js:373:12)
    at Object.<anonymous>.exports.postNewEmployee.formData [as postNewEmployee] (/Users/johanh/Kod/react-app/src/api/api.js:20:10)
    at Object.it (/Users/johanh/Kod/react-app/src/api/api.test.js:75:16)
    at Object.<anonymous> (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/build/jasmine-async.js:42:32)
    at attemptAsync (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1919:24)
    at QueueRunner.run (/Users/johanh/Kod/react-app/node_modules/react-scripts/node_modules/jest-jasmine2/vendor/jasmine-2.4.1.js:1874:9)

就像我说的,这只发生在测试中。在浏览器中可以正常工作。

我觉得我错过了一些明显的东西,但我就是看不出来。我查阅了fetch规范和dom文档,但都无济于事。什么好主意吗?

通常您不应该在单元测试中发出真正的请求。处理此问题的最佳方法是使用模拟而不是真正的fetch实现。

我假设你正在使用fetch的JS实现。所以你可以设置fetch为任何你想在你的测试。

import * as API from './api';
describe('postNewEmployee', () => {
  it('posts the form data asynchronously', () => {
    // set fetch to a mock that always returns a solved promise
    const fetch = jest.fn((url, options) => return Promise.resolve({status: 201}))
    global.fetch = fetch;
    let formData = {
      employee: {
        name: 'Test Person',
        email: 'test@person.nu',
        address: 'an adress 123'
      }
    };
    //test that fetch was called with the correct parameters
    expect(fetch.mock.calls[0][0]).toBe('http://localhost:3003')
    expect(fetch.mock.calls[0][1]).toEqual(formData)
    return API.postNewEmployee(formData)
      .then(json => {
        expect(json.status).toEqual(201);
      }).catch(error => {
        console.log(error);
      });
  });
});