Обяснено е заглавието Access-Control-Allow-Origin - с пример CORS

Често пъти при извикване на API можете да видите грешка в конзолата си, която изглежда така:

 Access to fetch at '//somesite.com' from origin '//yoursite.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin 

В тази публикация ще научим защо се случва тази грешка и как можете да я поправите.

Какво представлява Access-Control-Allow-Originзаглавката?

Access-Control-Allow-Originе заглавка на CORS. CORS или Cross Origin Resource Sharing е механизъм за браузърите да позволят на сайт, работещ в произход А, да поиска ресурси от произход Б.

Произходът не е само името на хоста, а комбинация от порт, име на хост и схема, като - //mysite.example.com:8080/

Ето пример за това къде това влиза в действие -

  1. Имам произход A: //mysite.comи аз искам да се получи средства от произхода Б: //yoursite.com.
  2. За да защити вашата сигурност, браузърът няма да ми позволи достъп до ресурси от yourite.com и ще блокира моята заявка.
  3. За да позволи на origin A да има достъп до вашите ресурси, вашият origin B ще трябва да уведоми браузъра, че е добре за мен да получавам ресурси от вашия източник.

Ето пример от Mozilla Developer Network, който обяснява това наистина добре:

С помощта на CORS браузърите позволяват на източниците да споделят ресурси помежду си.

Има няколко заглавки, които позволяват споделяне на ресурси по произход, но основният е Access-Control-Allow-Origin. Това казва на браузъра какви източници имат право да получават заявки от този сървър.

Кой трябва да зададе Access-Control-Allow-Origin?

За да разберете кой трябва да зададе този хедър, разгледайте този сценарий: Разглеждате уебсайт, който се използва за преглед и слушане на песни. Уебсайтът се опитва да направи връзка с вашата банка във фонов режим злонамерено.

И така, кой има крайната способност да попречи на този злонамерен уебсайт да открадне вашите данни от банката? Банката! Така че банката ще трябва да защити своите ресурси, като зададе Access-Control-Allow-Originзаглавката като част от отговора.

Само не забравяйте: произходът, отговорен за обслужването на ресурси, ще трябва да зададе тази заглавка.

Как да използвам и кога да предам този хедър

Ето пример за стойности, които можете да зададете:

  1. Access-Control-Allow-Origin : * : Позволява всеки произход.
  2. Access-Control-Allow-Origin : //mysite.com : Разрешаване на заявки само от mysite.com.

Вижте го в действие

Нека разгледаме един пример. Можете да проверите този код в моето репо GitHub.

Ще изградим сървър на произход А, //localhost:8000който ще изпрати низ от Hellos до apiкрайна точка. Ще се обадим с тази крайна точка, като създадем клиент с произход Б //localhost:3000и след това използваме извличане, за да поискаме ресурса. Очакваме да видим низа, Helloпредаден от произход A в конзолата на браузъра на произход B.

Да кажем, че имаме произход, //localhost:8000който обслужва този ресурс в /apiкрайна точка. Сървърът изпраща отговор със заглавката Access-Control-Allow-Origin.

const express = require("express"); const app = express(); const port = process.env.SERVER_PORT || 8000; // Add Access Control Allow Origin headers app.use((req, res, next) => { res.setHeader("Access-Control-Allow-Origin", "//yoursite.com"); res.header( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept" ); next(); }); app.get("/api", (req, res) => { res.json("Hello"); }); app.listen(port, () => console.log(`Listening on port ${port}`)); 

От страна на клиента можете да извикате тази крайна точка, като извикате по fetchследния начин:

fetch('//localhost:8000/api') .then(res => res.json()) .then(res => console.log(res)); 

Сега отворете конзолата на браузъра си, за да видите резултата.

Тъй като в момента заглавката е настроена да разрешава достъп само от //yoursite.com, браузърът ще блокира достъпа до ресурса и ще видите грешка в конзолата си.

Сега, за да поправите това, променете заглавките на това:

 res.setHeader("Access-Control-Allow-Origin", "*"); 

Проверете конзолата на браузъра си и сега ще можете да видите низа Hello.

Интересувате ли се от повече уроци и JSBytes от мен? Регистрирайте се за моя бюлетин.