如何在 fetch/axios 跨站请求中使用 JSONP

Posted

技术标签:

【中文标题】如何在 fetch/axios 跨站请求中使用 JSONP【英文标题】:How to use JSONP on fetch/axios cross-site requests 【发布时间】:2017-09-14 05:46:17 【问题描述】:

我正在尝试在 wikipedia API 上执行 GET 请求。如下使用 jQuery 可以正常工作:

$.ajax(
  url: 'https://en.wikipedia.org/w/api.php?format=json&action=query&generator=search&gsrnamespace=0&gsrlimit=10&prop=pageimages|extracts&pilimit=max&exintro&explaintext&exsentences=1&exlimit=max&gsrsearch=Test&callback=JSON_CALLBACK',
  type: 'GET',
  headers: 'X-Requested-With': 'XMLHttpRequest',
  crossDomain: true,
  dataType: 'jsonp'
).done(function(data) 
  console.log("Data: ", data);  
);

但我想使用 fetch 或 axios api,它在 pre-flight 停止,请求方法:OPTIONS。为什么它在 jQuery 中有效,而在其他 API 中无效?

axios.get('https://en.wikipedia.org/w/api.php?format=json&action=query&generator=search&gsrnamespace=0&gsrlimit=10&prop=pageimages|extracts&pilimit=max&exintro&explaintext&exsentences=1&exlimit=max&gsrsearch=Test&callback=JSON_CALLBACK', 
     headers: 'X-Requested-With': 'XMLHttpRequest',
                'content-type': 'text/plain'
    )
    .then(function (response) 
        console.log("Response: ", response);  
    );

我看到它可能与 GET 请求的 Content-Type 有关,在 jQuery 上默认似乎是 text/plain,但是我在尝试更改时没有成功以 text/html 形式发送的 fetch/axios 请求的内容类型。

对可能出现的问题有什么想法吗?

【问题讨论】:

我觉得axios不支持jsonp。 你说得对,我把它摘下来 【参考方案1】:

我发现问题与请求的内容类型无关。

问题是由于 API(fetch 和 axios)不支持 jsonp 请求。 jsonp 的使用对我来说不够清楚,我可以在这里找到一个很好的解释:http://***.com/a/6879276/4051961

虽然他们不支持它,但他们提供了执行 jsonp 请求的替代方法:

axios:https://github.com/mzabriskie/axios/blob/master/COOKBOOK.md#jsonp 获取:https://www.npmjs.com/package/fetch-jsonp

【讨论】:

【参考方案2】:

推荐使用 axios 访问 JSONP 的方式其实是不使用 axios:

    The Discussion on Why (not)

    A similar question

    Alternative Suggestion from Axios

简而言之安装:

npm install jsonp --save

像这样使用它:

var jsonp = require('jsonp');

jsonp('http://www.example.com/foo', null, function (err, data) 
  if (err) 
    console.error(err.message);
   else 
    console.log(data);
  
);

【讨论】:

【参考方案3】:

在 React 应用程序中遇到问题

Axios 不支持 JSONP,它们提供了执行 jsonp 请求的替代方案:

点击此链接可查看一些关于 axios 的 jsonp 文档: axios:https://github.com/mzabriskie/axios/blob/master/COOKBOOK.md#jsonp

这是我的文档:

第一步:$ npm install jsonp --save

第二步:

import jsonp from 'jsonp';

(位于组件的顶部)

第三步:在你的 React 组件中创建一个方法:

JSONP () 
        jsonp( "https://*YourUrlHere.jsonp",  name: 'Name Of JSONP Callback Function' , (error, data) => 
            if (error) 
                this.setState(
                    error,
                );
             else 
                this.setState(
                    data: data,
                );
            
        );
    

【讨论】:

npmjs.com/package/fetch-jsonp 也适用于 react 并且非常简单。【参考方案4】:

yarn add simple-jsonp-promisenpm install simple-jsonp-promise

import jsonp from 'simple-jsonp-promise'

async function Test () 
  const url = 'http://...'
  const params = param1: 1, param2: 2

  const response = await jsonp(url, data: params)
  console.log('response:', response)

【讨论】:

以上是关于如何在 fetch/axios 跨站请求中使用 JSONP的主要内容,如果未能解决你的问题,请参考以下文章

vue中简单的数据请求 fetch axios

React如何使用内置的fetch模块

Vue 接口 promise + fetch + axios + async 和 await

Vue 接口 promise + fetch + axios + async 和 await

如何在 PHP 中有效地防止跨站请求伪造 (CSRF)

CSRF(跨站请求伪造)在 Laravel 中无法正常工作