One of the most common errors we record, “Cannot read properties of undefined (reading ‘length’)”, turned up in our own logs recently while looking into an issue with Microsoft Edge and the Facebook sdk. Let’s dive into this error, what it means, and how to fix it.
Breaking down the Message
TypeError: Cannot read properties of undefined (reading 'length')
In older browsers, this might also be shown as:
Cannot read property 'length' of undefined
TypeError is a subset of JavaScript Error that is thrown when code attempts to do something that does not exist on the target object.
This message indicates that our code expects to have an object with a length
property, but that object was not present. length
is commonly used on string
and array
, but a custom object could also have this property.
This is a blocking error, and script execution will stop when this error occurs.
Understanding the Root Cause
This error can be thrown for a lot of reasons, as it is incredibly common to reference the length
property of string
or array
during everyday development. For example, if we had a function that acts on a string argument, but is called without a string, we would see this error.
function foo(myString) { if (myString.length >= 10) { // do something } } foo(); // Whoops! TypeError
In our case, we were intercepting a call to fetch
, and we had assumed the url
property would be a string.
But, dear developer, it was not always a string. 🤦♂️.
We had some code like this that intercepted fetch requests and recorded some metadata if the request was correct. It looked something like this:
ourInterceptedFetch(options) { if (options.url.length <= 0) { // fail out } }
We were doing appropriate defensive type checking to make sure that the options
argument had a valid url
property. Unfortunately, fetch also accepts options
to be any object with a stringifier: an object with a toString
method. Like this:
fetch({ toString: function() { return `https://whatever.com/`; } });
In this case, options.url
is undefined, so when we try to check options.url.length
, it blows up with our error, “Cannot read property ‘length’ of undefined”. Ugh.
While this may be valid, it is a bit weird, right? We thought so too.
How to Fix It
So how do we fix this and prevent it from happening again?
1. Understand why your object is undefined
First and foremost, you need to understand why this happened before you can fix it. You are probably not doing exactly the same thing we are, so the reason your object is undefined may be somewhat different. Consider:
- Are you relying on a network response to be a certain shape?
- Are you processing user-input?
- Is an external function or library calling into your code?
Or maybe its just a logical bug somewhere in your code.
2. Add Defensive Checking
Anytime you don’t completely control the input into your code, you need to be defensively checking that arguments have the correct shape. API response change, functions get updated, and users do terrible, terrible things.
For instance, if you have a fetch
request that receives a JSON response with a foo
string property, you might have a defensive check that looks like this:
fetch("https://example.com/api") .then(resp => { return resp.json(); }) .then(json => { if (!json || typeof json.foo != 'string') { // Record an error, the payload is not the expected shape. } });
3. Monitor Your Environment
You’ll need to make sure that the issue is really fixed and that the problem stops happening. Mistakes happen, APIs change, and users are unpredictable. Just because your application works today, doesn’t mean an error won’t be discovered tomorrow. Tracking when exceptional events happen to your users gives you the context to understand and fix bugs faster. Check out TrackJS Error Monitoring for the fastest and easiest way to get started.
The TypeError: Cannot read property 'length' of undefined
is one of the most common type errors in JavaScript. It occurs when the length
property is read on an undefined variable.
Error message:
TypeError: Cannot read properties of undefined (reading 'length')
Error Type:
TypeError
What Causes TypeError: Cannot Read Property Length of Undefined
Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined
is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property 'length' of undefined
.
TypeError: Cannot Read Property Length of Undefined Example
Here’s an example of a JavaScript TypeError: Cannot read property 'length' of undefined
thrown when the length
property is attempted to be read on an undefined variable:
function myFunc(a) {
console.log(a.length);
}
var myVar;
myFunc(myVar);
Since the variable myVar
is declared but not initialized, it is undefined. When it is passed to the myFunc()
function, the property length
is attempted to be accessed. Since a
is undefined at that point, running the code causes the following error:
Uncaught TypeError: Cannot read properties of undefined (reading 'length')
How to Avoid TypeError: Cannot Read Property Length of Undefined
When such an error is encountered, it should be ensured that the variable causing the error is assigned a value. The length
property is supported by data types such as arrays and strings. Custom objects can also have this property.
To avoid coming across situations where properties of undefined variables may be accessed accidentally, an if
check should be added before dealing with such variables:
if (myVar !== undefined) {
...
}
if (typeof(myVar) !== 'undefined') {
...
}
Updating the previous example to include an if
check:
function myFunc(a) {
if (a !== undefined) {
console.log(a.length);
}
}
var myVar;
myFunc(myVar);
Running the above code avoids the error since the property length
is only accessed if a
is not undefined
.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing JavaScript errors easier than ever. Sign Up Today!
As a JavaScript developer, I’m sure you’ve encountered the frustrating runtime TypeError Cannot read properties of undefined
. TypeScript gives you two ways of interpreting null
and undefined
types, also known as Type Check Modes, and one of them can avoid this easily overlooked TypeError.
Until TypeScript 2.0, there was only one type check mode — regular — and it considersnull
and undefined
as subtypes of all other types. This means null
and undefined
values are valid values for all types.
TypeScript 2.0 introduced Strict Type Check Mode (also referred to as strict null checking mode). Strict Type Check differs from Regular Type Check because it considers null
and undefined
types of their own.
I’ll show you how Regular Type Check handles undefined
(the same applies to null
) and how Strict Type Check prevents you from introducing unwanted behavior in our code, like that infamous TypeError Cannot read properties of undefined
.
When undefined becomes a problem
The function translatePowerLevel below takes a number as argument and returns strings one
, two
, many
or it's over 9000!
.
function translatePowerLevel(powerLevel: number): string {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
}
However, this code doesn’t handle 0, a valid input — yes, looking at you, Yamcha.
Yamcha’s Power Level
When JavaScript reaches the end of a function that has no explicit return, it returns undefined
.
The translatePowerLevel
function return value is typed explicitly as string
, but it is possibly also returning undefined
when the argument powerLevel
has the value 0. Why is TypeScript not triggering an error?
In Regular Type Check Mode, TypeScript is aware that a function might return undefined
. But at the same time, TypeScript infers the return type to be only of type string
because TypeScript is widening the undefined
type to string
type.
As another example, if you assign null
or undefined
to variables while in Regular Type Check Mode, TypeScript will infer these variables to be of type any
.
const coffee = null;
const tea = undefined;
Interpreting undefined
or null
as subtypes of all other types can lead to runtime problems. For example, if you try to get the length of the result of translateNumber(0)
, which is undefined
, JavaScript will throw this TypeError at runtime: Cannot read properties of undefined (reading 'length').
const powerLevel = translatePowerLevel(0); // undefined
console.log(powerLevel.length); // Uncaught TypeError: Cannot read properties of undefined (reading 'length')
Unfortunately, TypeScript’s Regular Type Check Mode is not able to alert you to when you may have made that mistake.
Strict Type Check Mode to the Rescue
Strict Type Check Mode changes how TypeScript interprets undefined
and null
values. But first, let‘s enable Strict Type Check Mode.
How to Enable Strict Type Check Mode in TypeScript
In the root of your project, there should be a tsconfig.json file
. This is the TypeScript’s configuration file and you can read more about it here.
// tsconfig.json example
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Inside compilerOptions
property, all we need to do is add the property "strictNullChecks": true
.
It will look something like this:
// tsconfig.json
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true,
"strictNullChecks": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Now that we have switched to Strict Type Check Mode, TypeScript throws this error for translatePowerLevel
function: Function lacks ending return statement and return type does not include 'undefined'
.
That error message is telling you the function is returning undefined
implicitly, but its return type does not include undefined
in it.
Awesome! TypeScript is now aware the return type does not match all possible return values, and this could lead to problems at runtime! But how can you match the return type to all possible return values?
You can either add a return statement so the function always returns a string
(solution #1), or change the return type from string
to string | undefined
(solution #2).
Match All Possible Return Values: Solution #1
Adding a return statement so it is always explicitly returning a value — in the code below, it is now returning the string zero
.
// Solution #1: add a return statement so it always returns a string
function translatePowerLevel(powerLevel: number): string {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
// new return statement
return 'zero';
}
Match All Possible Return Values: Solution #2
Make the undefined
return type explicit so wherever translatePowerLevel
is used, you have to handle nullish
values as well.
// Solution #2: return type as string | undefined
function translatePowerLevel(powerLevel: number): string | undefined {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
}
If you were to compile the following code again using Solution #2, TypeScript would throw the error Object is possibly 'undefined'
.
const powerLevel = translatePowerLevel(0); // undefined
console.log(powerLevel.length); // Object is possibly 'undefined'.
When you choose a solution like Solution #2, TypeScript expects you to write code that handles possible nullish
values.
There’s no reason not to use Strict Type Check Mode
Now you understand how TypeScript interprets null
and undefined
types and how you can migrate your project to Strict Mode.
If you are starting a new project, you should definitely enable Strict Type Check Mode from the beginning. And in case you will migrate from Regular to Strict Type Check, our team can help with strategies to do so in a less painful way.
At Bitovi we highly recommend using — or migrating to — Strict Type Check Mode for Angular application development, as it can help you produce better, more reliable code.
Need more help?
Bitovi has expert Angular consultants eager to help support your project. Schedule your free consultation call to get started.
The issue happen with v4 version (tested on v4.0.3, v4.0.5 and the latest v4.1.2)
With the same config and code base it compile with no problem in v3.9
Expected behavior:
No such error! No failing at internal level! (Plus it works in v3.9 and not v4)
text should not come as undefined! Or should be handled without problem!
Actual behavior:
In v3.9 the code compile with the same config with no problem! In v4 i get Cannot read property ‘length’ of undefined error! And internal failing!
Through the error stack! i get where the error happened and it was at the function computeLineStarts!
text is coming undefined! i did some console logging! And i got what file was been treated! And what text node were printing! The file is all normal and correct! A comment at the end was the last thing which after it the code fail!
Then i added another instruction after it! (A variable assignment const someVar = '';
) and the error went up! The last treated nodes before failing came more up! Here bellow the file at which my console.logging stopped at!
File on which the resolution failed at:
https://gist.github.com/MohamedLamineAllal/472cf2043a100cb03244de5fb1138034
When i added const someVar = "";
at the end! the last treated node was }
from
export interface IWebSocketDriver { readonly protocol: string; readonly readyState: number; readonly url: string; binaryType: BinaryType; readonly CONNECTING: number; readonly OPEN: number; readonly CLOSING: number; readonly CLOSED: number; setGetStreamObj: (getStreamObj: () => WebSocket | IWebSocketDriver) => IWebSocketDriver; onInit: () => IWebSocketDriver; onopen: ((this: IWebSocketDriver, ev: Event) => any) | null; onmessage: ((this: IWebSocketDriver, ev: MessageEvent) => any) | null; onclose: ((this: IWebSocketDriver, ev: CloseEvent) => any) | null; onerror: ((this: IWebSocketDriver, ev: Event) => any) | null; close(code?: number, reason?: string): void; send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void; } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<!!!!!!!!!!!!!!! here the last treated element /** * THINGS TO DO: * ============= * * decide and define the response output of all the functions * * consider a design that add useful information that are exchange platform dependent * * * * STREAMS : * Need to precise what form the returned object should have * * ok dodo */ const someVar = ''; // <=== added this
How i debugged!?
in tsc.js
ts.stringToToken = stringToToken; function computeLineStarts(text) { console.log('text: ') // <<<==== here console.log(text) var result = new Array(); var pos = 0;
And at
ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode; function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) { console.log('Source file: ') // <<<<<<<<<<<<<<<<<<<<<<<<= here console.log(sourceFile.path) console.log('================+++>') if (includeTrivia === void 0) { includeTrivia = false; } return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia); }
First Compilation execution (original file)
Without adding the last const someVar = '';
https://gist.github.com/MohamedLamineAllal/653fd4f597aa821f416a33e86d4514eb
Second compilation (after adding the last line)
https://gist.github.com/MohamedLamineAllal/022f6f285313aec30b82bb72238bcaeb
Always it fails at computeLineStarts() method! And because text is undefined.
Error stack
TypeError: Cannot read property 'length' of undefined at computeLineStarts (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:6528:27) at Object.getLineStarts (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:6581:60) at getCurrentLineMap (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:81810:59) at emitDetachedCommentsAndUpdateCommentsInfo (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:85144:94) at emitBodyWithDetachedComments (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:85007:17) at emitSourceFile (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:83873:21) at pipelineEmitWithHint (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:81887:24) at noEmitNotification (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:80586:9) at onEmitNode (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:70565:13) at onEmitNode (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:72333:13)
For the shared links i used typescript Version 4.1.2! Otherwise i tested with v4.0.3 and v4.0.5
tsconfig.json
{ "compilerOptions": { "declaration": true, "declarationDir": "./dist", "module": "commonjs", "noImplicitAny": true, "lib": ["ESNext", "DOM"], "outDir": "./dist", "target": "es6", "moduleResolution": "node", "resolveJsonModule": true, "esModuleInterop": true }, "typedocOptions": { "mode": "modules", "out": "docs" }, "include": ["src/**/*.ts", "src/**/*.json", "test"], "exclude": ["node_modules", "dist", "src/**/*.spec.ts", "src/**/*.test.ts"] }
Related Issues:
- TypeError: Cannot read property ‘length’ of undefined in computeLineStarts #40747
- TypeError: Cannot read property ‘length’ of undefined in watch mode and {allowJS: true} #35074
I am trying to read the json document from php and convert it needed in js, but an error occurs. :
cannot read properties of undefined (reading ‘length’)
What went wrong? How can I loop the result below without using length ?
Here’s the code:
What I have tried:
/*php */ $conn = db_connect(); $id = mysqli_fix_string( $conn, $id ); $Json_file = file_get_contents("files/sub/".$id."/".sub.json); print( $json_file ); /*.js */ $.ajax({ url: "./sub/view_sub.php", type:"GET", data: { id: id }, success: function( json ) { const result = JSON.parse( json ); console.log(result.sub) console.log(result.sub[1]); // OK result is 'serg' console.log(result.sub[2]); // OK result is 'dgf if( result.sub.length > 0 ){ <<== error let i = 0; for( const item of result.sub ){ foo_arr[id].input_text(i++, item ); } } } }); // console result >{1: 'serg', 2: 'dgf', 4: 'dfg ', 6: 'dfge ergre'} <== console.log(result.sub) uncaught typeError: Cannot read properties of undefined (reading 'length')
Solution 2
Quote:
This is my result /
console.log(result.sub) {1: 'serg', 2: 'dgf', 4: 'dfg ', 6: 'dfge ergre'}
Your result is not an array; it’s an object which happens to have numeric property names.
If you want to iterate over the properties of the object, you can use the Object.keys
method[^]:
const subKeys = Object.keys(result.sub); for (let i = 0; i < subKeys.length; i++) { foo_arr[id].input_text(i, result.sub[subKeys[i]]); }
Comments
Solution 1
Try using:
if( result.length > 0 )
Example:
const fruits = ["Banana", "Orange", "Apple", "Mango"]; let length = fruits.length;
result returns:
4
Comments
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
Top Experts | |
Last 24hrs | This month |
CodeProject,
20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8
+1 (416) 849-8900
От автора: чтобы вернуть сообщество разработчиков, мы рассмотрели нашу базу данных по тысячам проектов и нашли 10 самых распространённых ошибок в JavaScript. Мы собираемся показать вам, что к ним приводит и как это предотвратить. Если ни одна ошибка JavaScript не встречается в вашем коде, это делает вас лучшим разработчиком.
Поскольку всем управляют данные, мы собрали, проанализировали и оценили первые 10 ошибок JavaScript. Rollbar собирает все ошибки из каждого проекта и суммирует, сколько раз каждая из них возникала. Мы делаем это, группируя ошибки в соответствии с их отпечатками пальцев . В принципе, группируется по две ошибки, если вторая — это просто повторение первой. Это дает пользователям хороший обзор вместо огромной свалки, какую вы видели в файле журнала.
Мы сосредоточились на ошибках, которые скорее всего повлияют на вас и ваших пользователей. Чтобы сделать это, мы оценили ошибки по количеству проектов, испытывающихся в разных компаниях. Если бы мы посмотрели только на общее количество раз, когда произошла каждая ошибка, то клиенты большого объема могли бы подавить набор данных с ошибками, которые не имеют отношения к большинству читателей.
Вот первые 10 ошибок JavaScript:
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнее
Ошибки были сокращены для удобства чтения. Давайте погрузимся глубже в каждую, чтобы определить, что может вызвать её, и как избежать их появления.
1. Uncaught TypeError: Cannot read property
Если вы разработчик JavaScript, то, вероятно, видели эту ошибку очень много раз. Это происходит в Chrome, когда вы читаете свойство или вызываете метод на неопределенный объект. Это можно очень легко проверить в консоли разработчика Chrome.
Это может произойти по многим причинам, но чаще всего это неправильная инициализация состояния при рендеринге компонентов пользовательского интерфейса. Давайте рассмотрим пример того, как это может произойти в реальном приложении. Мы выберем React, но те же принципы неправильной инициализации применимы и к Angular, Vue или любой другой структуре.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Quiz extends Component { componentWillMount() { axios.get(‘/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); } } |
Здесь понимаются две важные вещи:
Состояние компонента (например, this.state ) начинает жизнь как undefined.
Когда вы извлекаете данные асинхронно, компонент будет отображаться как минимум один раз перед загрузкой данных — независимо от того, выбрана ли она в конструкторе componentWillMount или componentDidMount . Когда Quiz отображается впервые, this.state.items не определен. Это, в свою очередь, означает, что ItemList получает элементы как неопределенные, и вы получаете сообщение об ошибке «Uncaught TypeError: Невозможно прочитать карту свойств» в консоли.
Это легко исправить. Самый простой способ: инициализировать состояние с разумными значениями по умолчанию в конструкторе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Quiz extends Component { // Added this: constructor(props) { super(props); // Assign state itself, and a default value for items this.state = { items: [] }; } componentWillMount() { axios.get(‘/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); } } |
Код в вашем приложении может отличаться, но мы надеемся, что дали вам достаточно информации, чтобы исправить или избежать этой проблемы. Если нет, продолжайте читать, потому что далее мы рассмотрим больше примеров связанных с ошибками.
2. TypeError: ‘undefined’ is not an object (evaluating
Эта ошибка возникает в Safari при чтении свойства или вызове метода для неопределенного объекта. Вы можете проверить это в консоли разработчика Safari. Это по сути то же самое, что и вышеприведенная ошибка для Chrome, только Safari использует другое сообщение об ошибке.
3. TypeError: null is not an object (evaluating
Это ошибка, которая возникает в Safari при чтении свойства или вызове метода для пустого объекта. Проверить это можно в консоли разработчика Safari.
Интересно, что в JavaScript значения null и undefined не совпадают, поэтому мы видим два разных сообщения об ошибках. Undefined обычно является переменной, которая не была назначена, а null означает, что значение пустое. Чтобы убедиться, что они не одно и то же, попробуйте использовать строгий оператор равенства:
Один из способов, которым эта ошибка может возникнуть в реальном мире — это попытка использовать элемент DOM в JavaScript перед загрузкой элемента. Это потому, что DOM API возвращает null для ссылок на пустые объекты.
Любой JS-код, который выполняет и обрабатывает элементы DOM, должен выполняться после создания элементов DOM. JS-код интерпретируется сверху вниз, как изложено в HTML. Итак, если перед элементами DOM есть тег, код JS в теге скрипта будет выполняться, когда браузер анализирует HTML-страницу. Вы получите эту ошибку, если элементы DOM не были созданы до загрузки сценария.
В этом примере мы можем решить проблему, добавив прослушиватель событий, который уведомит нас, когда страница будет готова. После addEventListener метод init() может использовать элементы DOM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script> function init() { var myButton = document.getElementById(«myButton»); var myTextfield = document.getElementById(«myTextfield»); myButton.onclick = function() { var userName = myTextfield.value; } } document.addEventListener(‘readystatechange’, function() { if (document.readyState === «complete») { init(); } }); </script> <form> <input type=«text» id=«myTextfield» placeholder=«Type your name» /> <input type=«button» id=«myButton» value=«Go» /> </form> |
4. (unknown): Script error
Ошибка скрипта возникает, когда ошибка неперехваченного JavaScript пересекает границы домена и нарушает политику перекрестного происхождения. Например, если вы размещаете свой код JavaScript на CDN, любые неперехваченные ошибки (ошибки, которые появляются в обработчике window.onerror, вместо того, чтобы быть пойманным в try-catch) будут переданы как просто «Script error» вместо того, чтобы содержать полезную информацию. Эта мера безопасности браузера предназначена для предотвращения передачи данных по доменам, которые в противном случае не были бы допущены к коммуникации.
Чтобы получить реальные сообщения об ошибках, выполните следующие действия:
1. Отправьте заголовок Access-Control-Allow-Origin
Установка заголовка Access-Control-Allow-Origin в * означает, что к ресурсу можно получить доступ из любого домена. Вы можете заменить * своим доменом, если необходимо: например, Access-Control-Allow-Origin: www.example.com . Если вы используете CDN из-за проблем с кэшированием, которые могут возникнуть, обработка нескольких доменов становится сложной и нельзя не приложить усилий. Подробнее см. здесь.
Вот несколько примеров того, как установить этот заголовок в различных средах:
Apache
В папках, где будут храниться ваши файлы JavaScript, создайте файл .htaccess со следующим содержимым:
Header add Access—Control—Allow—Origin «*» |
Nginx
Добавьте директиву add_header в блок местоположения, который служит файлам JavaScript:
location ~ ^/assets/ { add_header Access—Control—Allow—Origin *; } |
HAProxy
Добавьте в ресурс, где будут загружены файлы JavaScript:
rspadd Access—Control—Allow—Origin: * |
2. Установите crossorigin = «anonymous» в теге скрипта
В HTML-источнике для каждого из сценариев, где вы установите заголовок Access-Control-Allow-Origin, в теге SCRIPT установите crossorigin=»anonymous». Убедитесь, что заголовок отправляется для файла сценария, перед добавлением свойства crossorigin в тег скрипта. В Firefox, если атрибут crossorigin присутствует, но заголовок Access-Control-Allow-Origin отсутствует, сценарий не будет выполнен.
5. TypeError: Object doesn’t support property
Это ошибка, которая возникает в IE при вызове неопределенного метода. Вы можете проверить это в IE Developer Console.
Это эквивалентно ошибке «TypeError: ‘undefined’ is not a function» в Chrome. Да, разные браузеры могут иметь разные сообщения для одной и той же ошибки.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнее
Это обычная проблема для IE в веб-приложениях, использующих пространство имен JavaScript. Когда это так, проблема в 99,9% случаев— это неспособность IE связать методы в текущем пространстве имен с ключевым словом this. Например, если у вас есть пространство имен имен Rollbar с помощью метода isAwesome. Обычно, если вы находитесь в пространстве имен Rollbar вы можете вызвать метод isAwesome со следующим синтаксисом:
Chrome, Firefox и Opera с радостью согласятся с этим синтаксисом. С другой стороны, IE не станет. Таким образом, самая безопасная ставка при использовании JS namespacing — это префикс с фактическим пространством имен.
6. TypeError: ‘undefined’ is not a function
Это ошибка, возникающая в Chrome при вызове неопределенной функции. Вы можете протестировать это в консоли разработчика Chrome и в Mozilla Firefox.
Поскольку на протяжении многих лет методы кодирования JavaScript и шаблоны проектирования становятся все более изощренными, наблюдается соответствующее увеличение распространения областей самореференции в обратных вызовах и закрытиях, которые являются довольно распространенным источником этой путаницы.
Рассмотрим фрагмент кода:
function clearBoard(){ alert(«Cleared»); } document.addEventListener(«click», function(){ this.clearBoard(); // what is “this” ? }); |
Выполнение вышеуказанного кода приводит к следующей ошибке: «Uncaught TypeError: undefined is not function». Причина, по которой вы получаете эту ошибку, заключается в том, что при вызове setTimeout() вы вызываете window.setTimeout(). В результате анонимная функция, передаваемая setTimeout(), определяется в контексте объекта окна, у которого нет clearBoard().
Традиционное решение, совместимое со старым браузером — просто сохранить ссылку на this в переменной, которая затем может быть унаследована закрытием. Например:
var self=this; // save reference to ‘this’, while it’s still this! document.addEventListener(«click», function(){ self.clearBoard(); }); |
Кроме того, в новых браузерах для передачи правильной ссылки вы можете использовать метод bind():
document.addEventListener(«click»,this.clearBoard.bind(this)); |
7. Uncaught RangeError: Maximum call stack
Это ошибка, которая возникает в Chrome при нескольких обстоятельствах. Одно из них — когда вы вызываете рекурсивную функцию, которая не завершается. Вы можете протестировать это в консоли разработчика Chrome.
Это также может произойти, если вы передадите значение функции, находящейся за пределами допустимого диапазона. Многие функции принимают только определенный диапазон чисел для своих входных значений. Например, Number.toExponential(digits) и N umber.toFixed(digits) принимают цифры от 0 до 20, а Number.toPrecision(digits) принимают цифры от 1 до 21.
var a = new Array(4294967295); //OK var b = new Array(—1); //range error var num = 2.555555; document.writeln(num.toExponential(4)); //OK document.writeln(num.toExponential(—2)); //range error! num = 2.9999; document.writeln(num.toFixed(2)); //OK document.writeln(num.toFixed(25)); //range error! num = 2.3456; document.writeln(num.toPrecision(1)); //OK document.writeln(num.toPrecision(22)); //range error! |
8. TypeError: Cannot read property ‘length’
Это ошибка, которая возникает в Chrome из-за свойства длины чтения для неопределенной переменной. Вы можете протестировать это в консоли разработчика Chrome.
Обычно вы определяете длину, определенную в массиве, но вы можете столкнуться с этой ошибкой, если массив не инициализирован или если имя переменной скрыто в другом контексте. Давайте рассмотрим эту ошибку на следующем примере.
var testArray= [«Test»]; function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); } } testFunction(); |
Когда вы объявляете функцию с параметрами, эти параметры становятся локальными. Это означает, что даже если у вас есть переменные с именами testArray , параметры с одинаковыми именами внутри функции будут по-прежнему рассматриваться как локальные.
У вас есть два способа решить эту проблему:
1. Удалите параметры в объявлении функции (оказывается, вы хотите получить доступ к тем переменным, которые объявлены вне функции, поэтому вам не нужны параметры для вашей функции):
var testArray = [«Test»]; /* Precondition: defined testArray outside of a function */ function testFunction(/* No params */) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); } } testFunction(); |
2. Вызовите функцию, передав ей массив, который мы объявили:
var testArray = [«Test»]; function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); } } testFunction(testArray); |
9. Uncaught TypeError: Cannot set property
Когда мы пытаемся получить доступ к неопределенной переменной, она всегда возвращает undefined, а мы не можем получить или установить любое свойство undefined. В этом случае приложение будет выбрасывать “Uncaught TypeError cannot set property of undefined.”
Например, в браузере Chrome:
Если объект test не существует, будет выдаваться ошибка: “Uncaught TypeError cannot set property of undefined.”
10. ReferenceError: event is not defined
Эта ошибка возникает при попытке получить доступ к переменной, которая не определена или находится за пределами текущей области. Вы можете легко протестировать её в браузере Chrome.
Если вы получаете эту ошибку при использовании системы обработки событий, убедитесь, что вы используете объект события, переданный в качестве параметра. Старые браузеры, такие как IE, предлагают событие глобальной переменной, но не поддерживаются во всех браузерах. Библиотеки, подобные jQuery, пытаются нормализовать это поведение. Тем не менее, лучше использовать тот объект, который передается в функцию обработчика событий.
document.addEventListener(«mousemove», function (event) { console.log(event); }) |
Вывод
Мы надеемся, что вы узнали что-то новое и сможете избежать ошибок в будущем или, что это руководство помогло вам решить возникшую проблему. Тем не менее, даже при использовании лучших практик в производстве появляются неожиданные ошибки. Важно иметь видимость ошибок, которые влияют на пользователей, и хорошие инструменты для их быстрого решения.
Rollbar предлагает уникальные возможности для приложений JavaScript, таких как телеметрия, которые сообщают вам, что произошло в браузере пользователя, что приводит к ошибке. Это прозрение, которого у вас нет за пределами локальной консоли разработчика.
Автор: Jason Skowronski
Источник: //rollbar.com/
Редакция: Команда webformyself.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Узнать подробнее
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Смотреть