【问题标题】:fetch API returning an empty string获取返回空字符串的 API
【发布时间】:2017-06-14 18:40:13
【问题描述】:

我正在尝试使用 fetch API 获取页面的 HTML。这是我的代码。

var quizUrl = 'http://www.lipsum.com/';
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/html');
fetch(quizUrl,{
    mode: 'no-cors',
    method: 'get',
    headers: myHeaders
}).then(function(response) {
    response.text().then(function(text) {
        console.log(text);
    })
}).catch(function(err) {
  console.log(err)
});

它返回空字符串。任何猜测为什么它不起作用?

【问题讨论】:

  • 当您查看 Web 控制台时会看到什么?
  • 另外:Content-Type request 标头与响应的类型无关。您不想在上面的请求中指定它,您没有将 HTML 发送到服务器。
  • 打开 chrome 检查器并转到 [网络] 点击并重试。您将看到 xhr 日志。您可以从那里看到整个请求/响应正文。先检查body是否为空。
  • @modernator,你可以自己试试。请求成功,但响应为'opaque',即js不可用。

标签: javascript fetch-api


【解决方案1】:

关于Request.mode'no-cors' (来自MDN,强调我的)

防止方法成为除 HEAD、GET 或 POST 之外的任何方法。如果任何 ServiceWorkers 拦截了这些请求,它们可能不会添加或覆盖除 these 之外的任何标头。此外,JavaScript 可能无法访问生成的 Response 的任何属性。这可确保 ServiceWorker 不会影响 Web 的语义,并防止因跨域泄漏数据而引起的安全和隐私问题。 p>

所以这将启用请求,但会将响应设置为opaque,也就是说,您将无法从中获取任何信息,除非知道目标在那里。

由于您正在尝试获取跨域域,所以除了代理路由之外别无他法。


PS:这是一个 sn-p,显示请求确实是不透明的:

var quizUrl = 'http://www.lipsum.com/';
fetch(quizUrl, {
  mode: 'no-cors',
  method: 'get'
}).then(function(response) {
  console.log(response.type)
}).catch(function(err) {
  console.log(err) // this won't trigger because there is no actual error
});

【讨论】:

【解决方案2】:

我想这可能会有所帮助,使用如下:

fetch('/url/to/server')
.then(res => {
    return res.text();
})
.then(data => {
    $('#container').html(data);
});

在服务器端,将内容作为纯文本返回,而不设置标题内容类型。

我用$('#container')代表你想要的容器 检索到的 html 数据。

获取 json 数据的区别在于使用 res.json() 代替 res.text() 另外,不要附加任何标题

【讨论】:

【解决方案3】:

如果您有自己的后端,请尝试(在您的后端)创建一个从 API 检索信息的函数,并使用您的前端从您的函数中检索信息。出于安全原因,某些 API 不允许直接通过浏览器(前端)检索数据。

总结:

==>从后端创建一个从 API 检索信息的函数

==>然后从前端创建一个函数,从后端返回的函数中检索数据

【讨论】:

    【解决方案4】:

    2021 年回答:以防万一您在这里寻找如何使用 async/await 或 Promise 发出 GET 和 POST Fetch api 请求(与 axios 相比)。

    我用jsonplaceholder fake API来演示:

    使用 async/await 获取 api GET 请求:

             const asyncGetCall = async () => {
                try {
                    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
                     const data = await response.json();
                    // enter you logic when the fetch is successful
                     console.log(data);
                   } catch(error) {
                // enter your logic for when there is an error (ex. error toast)
                      console.log(error)
                     } 
                }
    
    
              asyncGetCall()
    

    使用 async/await 获取 api POST 请求:

        const asyncPostCall = async () => {
                try {
                    const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
                     method: 'POST',
                     headers: {
                       'Content-Type': 'application/json'
                       },
                       body: JSON.stringify({
                 // your expected POST request payload goes here
                         title: "My post title",
                         body: "My post content."
                        })
                     });
                     const data = await response.json();
                  // enter you logic when the fetch is successful
                     console.log(data);
                   } catch(error) {
                 // enter your logic for when there is an error (ex. error toast)
    
                      console.log(error)
                     } 
                }
    
    asyncPostCall()
    

    使用 Promises 获取请求:

      fetch('https://jsonplaceholder.typicode.com/posts')
      .then(res => res.json())
      .then(data => {
       // enter you logic when the fetch is successful
        console.log(data)
      })
      .catch(error => {
        // enter your logic for when there is an error (ex. error toast)
       console.log(error)
      })
    

    使用 Promises 的 POST 请求:

    fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
       body: JSON.stringify({
         // your expected POST request payload goes here
          title: "My post title",
          body: "My post content."
          })
    })
      .then(res => res.json())
      .then(data => {
       // enter you logic when the fetch is successful
        console.log(data)
      })
      .catch(error => {
      // enter your logic for when there is an error (ex. error toast)
       console.log(error)
      })  
    

    使用 Axios 获取请求:

            const axiosGetCall = async () => {
                try {
                  const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
        // enter you logic when the fetch is successful
                  console.log(`data: `, data)
               
                } catch (error) {
        // enter your logic for when there is an error (ex. error toast)
                  console.log(`error: `, error)
                }
              }
        
        axiosGetCall()
    

    使用 Axios 的 POST 请求:

    const axiosPostCall = async () => {
        try {
          const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts',  {
          // your expected POST request payload goes here
          title: "My post title",
          body: "My post content."
          })
       // enter you logic when the fetch is successful
          console.log(`data: `, data)
       
        } catch (error) {
      // enter your logic for when there is an error (ex. error toast)
          console.log(`error: `, error)
        }
      }
    
    
    axiosPostCall()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多