获取返回空字符串的 API

Posted

技术标签:

【中文标题】获取返回空字符串的 API【英文标题】:fetch API returning an empty string 【发布时间】: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不可用。 【参考方案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
);

【讨论】:

另外我不会复制@T.J.Crowder's comment 说Content-Type 与这里无关,但这是一个好点! 跨域读取阻止 (CORB) 阻止了 MIME 类型为 text/html 的跨域响应 data.sfgov.org/Geographic-Locations-and-Boundaries/…。有关详细信息,请参阅chromestatus.com/feature/5629709824032768。【参考方案2】:

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

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

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

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

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

【讨论】:

无法加载 data.sfgov.org/d/u5j3-svi6:从“data.sfgov.org/d/u5j3-svi6”重定向到“data.sfgov.org/Geographic-Locations-and-Boundaries/…”已被 CORS 策略阻止:没有“Access-Control-Allow-Origin”标头出现在请求的资源。因此,Origin 'localhost:10' 不允许访问。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。 我收到错误:跨域读取阻止 (CORB) 阻止了 MIME 类型为 text/html 的跨域响应 data.sfgov.org/Geographic-Locations-and-Boundaries/…。有关详细信息,请参阅chromestatus.com/feature/5629709824032768。 这是一个服务器配置,看来你是在尝试从不允许跨域访问的服务器获取。 如果你要用 jQuery 来做这件事,你可以这样做 $('#container').load('url/to/server/'); 我可以添加答案,以防替换“容器”$('#container').html(data.value);【参考方案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()

【讨论】:

以上是关于获取返回空字符串的 API的主要内容,如果未能解决你的问题,请参考以下文章

PB中取字符串子串的函数是啥

数据处理函数

如何在不接收空字符串的情况下获取主板 ID?

如何在没有编译器警告的情况下返回对空字符串的 const 引用?

如何获取某个字符在字符串中的位置

符串的最长无重复字符的子串长度