42

I am trying to get a page's HTML using fetch API. Here is my code.

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)
});

It returns empty string. Any guesses why it doesn't work?

4
  • What do you see when you look in the web console? Commented Jan 29, 2017 at 14:16
  • 4
    Also: The Content-Type request header has nothing to do with the type of the response. You don't want to specify it in the request above, you're not sending HTML to the server. Commented Jan 29, 2017 at 14:16
  • Open the chrome inspector and go to [Network] tap and try again. You'll see the xhr logs. You can see the whole request/response body from there. Check the body is empty first. Commented Jan 29, 2017 at 14:29
  • 1
    @modernator, you can try it yourself. The request is successful, but the response is 'opaque' i.e not available for js. Commented Jan 29, 2017 at 14:33

4 Answers 4

66

I guess this might help, use as below:

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

And in server side, return content as plain text without setting header content-type.

I used $('#container') to represent the container that you want the html data to go after retrieving it.

The difference with fetching json data is using res.json() in place of res.text() And also, don't append any headers

Sign up to request clarification or add additional context in comments.

5 Comments

Failed to load data.sfgov.org/d/u5j3-svi6: Redirect from 'data.sfgov.org/d/u5j3-svi6' to 'data.sfgov.org/Geographic-Locations-and-Boundaries/…' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:10' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I got error : Cross-Origin Read Blocking (CORB) blocked cross-origin response data.sfgov.org/Geographic-Locations-and-Boundaries/… with MIME type text/html. See chromestatus.com/feature/5629709824032768 for more details.
That is a server configuration, seems you were trying to fetch from a server that does not allow cross origin access.
if you're gonna do that with jQuery you can just do $('#container').load('url/to/server/');
I could add to the answer, in case to replace the content at "container" $('#container').html(data.value);
24

About the Request.mode'no-cors' (from MDN, emphasis mine)

Prevents the method from being anything other than HEAD, GET or POST. If any ServiceWorkers intercept these requests, they may not add or override any headers except for these. In addition, JavaScript may not access any properties of the resulting Response. This ensures that ServiceWorkers do not affect the semantics of the Web and prevents security and privacy issues arising from leaking data across domains.

So this will enable the request, but will make the Response as opaque, i.e, you won't be able to get anything from it, except knowing that the target is there.

Since you are trying to fetch a cross-origin domain, nothing much to do than a proxy routing.


PS : here is a snippet showing you that the request is indeed opaque :

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 Comments

Also I won't copy @T.J.Crowder's comment saying that Content-Type has nothing to do here, but it's a good point !
Cross-Origin Read Blocking (CORB) blocked cross-origin response data.sfgov.org/Geographic-Locations-and-Boundaries/… with MIME type text/html. See chromestatus.com/feature/5629709824032768 for more details.
2

2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.

I'm using jsonplaceholder fake API to demonstrate:

Fetch api GET request using async/await:

         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()

Fetch api POST request using async/await:

    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()

GET request using 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)
  })

POST request using Promises:

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)
  })  

GET request using 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()

POST request using Axios:

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()

Comments

0

If you have your own backend, try making a function (in your backend) that retrieves information from the API and use your frontend to retrieve the information from your function. Some APIs, for security reasons, do not allow data to be retrieved directly via the browser (frontend).

Summary:

==>Create a function from your backend that retrieves information from the API

==>Then make a function from your frontend that retrieves data from the function returned by your backend

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.